2016-12-21 9 views
1

私は以下のようなデータフレームを持っています。3つの募集サイト(サイト)と5募集年(年)に従って平均睡眠時間(SLP)が表示されるマトリックスを作成します。データフレームから行列を作成するには?

SLP site year 
8.6 1 2008 
7.2 1 2005 
6.4 2 2006 
9.5 3 2007 
6.1 2 2009 
3.6 1 2005 
8.6 1 2008 
7.2 1 2005 
6.4 2 2006 
9.5 3 2007 
6.1 2 2009 
5.1 3 2008 
2.1 2 2006 

マイ所望の出力である:

 1  2  3 
2005 6.00 -  - 
2006 -  4.97 - 
2007 -  -  9.5 
2008 8.60 -  5.1 
2009 -  6.10 - 

列名は、サイトの変数であり、列名は、各セル内の年の値の変数は、SLPの平均値です。これはどうすればいいですか?

答えて

3

我々はここでbase R

から
with(df1, tapply(SLP, list(year, site), FUN = mean)) 
4

acast

library(reshape2) 
acast(df1, year~site, value.var="SLP", mean) 

またはtapplyを使用してを使用することができます何のパッケージを使用していないいくつかの異なるソリューションです:

1)tapplyこれはパッケージを使用しません。これは、NAの"matrix"出力が空のセルの値生成:与える

tapply(DF$SLP, DF[c("year", "site")], mean) 

 site 
year  1  2 3 
    2005 6.0  NA NA 
    2006 NA 4.966667 NA 
    2007 NA  NA 9.5 
    2008 8.6  NA 5.1 
    2009 NA 6.100000 NA 

2)凝集体/ XTABSこれはaggregate + xtabsを使用します。これは、空のセルのためのゼロ値を持つクラスc("xtabs", "table")のオブジェクト作成:

fo <- SLP ~ year + site 
xtabs(fo, aggregate(fo, DF, mean)) 

与えると、

 site 
year   1  2  3 
    2005 6.000000 0.000000 0.000000 
    2006 0.000000 4.966667 0.000000 
    2007 0.000000 0.000000 9.500000 
    2008 8.600000 0.000000 5.100000 
    2009 0.000000 6.100000 0.000000 

3)凝集/整形これもaggregateを使用するが、reshapeなくxtabsを使用します。それは、空のセルに対してNAを有するデータフレームrを与える。最後の行は、列名を従来の解決策と一致させ、重要でない場合は省略することができます。

ag <- aggregate(SLP ~ site + year, DF, mean) 
r <- reshape(ag, dir = "wide", idvar = "year", timevar = "site") 
names(r) <- sub(".*[.]", "", names(r)) 

与える:

> r 
    year 1  2 3 
1 2005 6.0  NA NA 
3 2006 NA 4.966667 NA 
5 2007 NA  NA 9.5 
2 2008 8.6  NA 5.1 
4 2009 NA 6.100000 NA 

注:使用再現形で入力DFである:

DF <- structure(list(SLP = c(8.6, 7.2, 6.4, 9.5, 6.1, 3.6, 8.6, 7.2, 
6.4, 9.5, 6.1, 5.1, 2.1), site = c(1L, 1L, 2L, 3L, 2L, 1L, 1L, 
1L, 2L, 3L, 2L, 3L, 2L), year = c(2008L, 2005L, 2006L, 2007L, 
2009L, 2005L, 2008L, 2005L, 2006L, 2007L, 2009L, 2008L, 2006L 
)), .Names = c("SLP", "site", "year"), class = "data.frame", row.names = c(NA, 
-13L)) 
2

別の溶液

library(tidyr) 
library(dplyr) 

df%>% 
    group_by(year, site) %>% 
    summarise(m=mean(SLP)) %>% 
    spread(site, m)%>% 
as.matrix() 
+0

"。"あなたのコマンドの最初の引数(例えば、 'df%>%group_by(year、site)')は最初の2行と同様に動作します。 Tidyverse動詞は、データフレームを最初の引数として自動的に期待し、そうでなければ指定しない限り、パイプラインされているものを使用します。 –

+0

それを指摘していただきありがとうございます、@RoseHartman – Adam

0

@ g-grothendieckのxtabsを利用して、これをtableifelseと組み合わせて同じ結果を返すことができます。

# get a count of the number of observations per matrix cell (filling 0s with 1) 
tempTab <- ifelse(with(df, table(year, + site)) == 0, 1, with(df, table(year, + site))) 

tempTab 

year 1 2 3 
    2005 3 1 1 
    2006 1 3 1 
    2007 1 1 2 
    2008 2 1 1 
    2009 1 2 1 

今複数の観察結果は、平均を得るためにtempTabによって細胞と分裂しているときの値の合計を返すxtabsを使用します。

xtabs(SLP ~ year + site, df)/tempTab 
     site 
year   1  2  3 
    2005 6.000000 0.000000 0.000000 
    2006 0.000000 4.966667 0.000000 
    2007 0.000000 0.000000 9.500000 
    2008 8.600000 0.000000 5.100000 
    2009 0.000000 6.100000 0.000000 
関連する問題