2011-12-11 3 views
3

私はかなり複雑であると確信しています。そして2つの因子変数(ここでは:sexunemp):私は、p(v3からv1こちら)変数を持つデータフレームを持ってサマリーテーブルを作成するプロセスの簡素化

> head(df) 
    sex unemp v1 v2 v3 
1 0  0 2 4 4 
2 0  0 2 1 1 
3 1  0 3 3 5 
4 1  1 2 3 5 
5 0  0 1 2 5 
6 1  0 3 5 4 

私は今(すなわちコンピューティングの中央値を変更し、意味したいと思いますし、その後再配置しますその結果得られたデータフレームは、男性または女性のための(次のようになりサマリー表)ような方法で自分のデータ):

library(plyr) 
## generate data 
set.seed(1) 
df <- data.frame(sex=rbinom(100, 1, 0.5), 
       unemp=rbinom(100, 1, 0.2), 
       v1=sample(1:5, 100, replace=TRUE), 
       v2=sample(1:5, 100, replace=TRUE), 
       v3=sample(1:5, 100, replace=TRUE) 
       ) 
head(df) 

## compute mean and median for all variables by sex and unemp 
df.mean <- ddply(df, .(unemp, sex), .fun=colMeans, na.rm=TRUE) 
df.mean 
df.median <- ddply(df, .(unemp, sex), .fun=function(x)apply(x,2,median, na.rm=TRUE)) 
df.median 

## rearrange summary table 
df.res.men <- cbind(t(subset(df.median, sex==0 & unemp==1)), 
       t(subset(df.median, sex==0 & unemp==0)), 
       t(subset(df.mean, sex==0 & unemp==1)), 
       t(subset(df.mean, sex==0 & unemp==0))) 
df.res.men <- df.res.men[-c(1:2),] 
colnames(df.res.men) <- c("median.unemp.1", "median.unemp.0", 
          "mean.unemp.1", "mean.unemp.0") 
df.res.men 
:ここ

> df.res.men 
    median.unemp.1 median.unemp.0 mean.unemp.1 mean.unemp.0 
v1   2.0   2.0  2.666667  2.391304 
v2   2.0   3.5  2.500000  3.369565 
v3   4.5   3.0  4.166667  2.956522 

は完全なコードです10

答えて

5

はここでここに1つのアプローチ

library(plyr); library(reshape2) 
dfm <- melt(df, id = c('sex', 'unemp')) 
df2 <- ddply(dfm, .(variable, unemp, sex), summarize, 
    avg = mean(value), med = median(value)) 

df2m <- melt(df2, id = 1:3, variable.name = 'sum_fun') 
df_0 <- dcast(df2m, sex + variable ~ sum_fun + unemp, subset = .(sex == 0)) 

    sex variable avg_0 avg_1 med_0 med_1 
1 0  v1 2.794872 3.0000  3 3.5 
2 0  v2 3.102564 2.8750  3 3.0 
3 0  v3 3.205128 3.1875  3 4.0 
+0

ありがとうございました!私はそれが私が探していたものだと思います。 –

+0

@Ramnath - 'reshape'と' reshape2'の間の機能の変化をキャッチしてくれてありがとう。誰かを混乱させるのではなく、私は自分の答えを削除しました。また、あなたの+1。 –

+0

@ Josh。私はあなたの答えを保つべきだと思います。それは非常にエレガントです。あなたは、機能が 'reshape'からのもので、' reshape2'から削除されたことを明確にするノートを追加することができます。 – Ramnath

2

であるだけではreshapeを使用して、2つのラインのソリューションです。デフォルトの列名には少しの作業が必要ですが、melt()cast()文の構文はうまく表現されています。

一つの重要な注意事項 - 。私はそれを指摘するためにRamnathにc(mean, median)おかげで以下やったようreshapeとは異なり、reshape2は、そのfun.aggregate引数として要約関数名のベクトルを取ることができない。)

library(reshape) 
dmelt <- melt(df, id=c('sex', 'unemp')) 

# Results for sex 0 
cast(dmelt, variable ~ unemp, c(mean, median), subset = sex==0) 
# variable 0_mean 0_median 1_mean 1_median 
# 1  v1 2.391304  2.0 2.666667  2.0 
# 2  v2 3.369565  3.5 2.500000  2.0 
# 3  v3 2.956522  3.0 4.166667  4.5 

# Results for sex 1 
cast(dmelt, variable ~ unemp, c(mean, median), subset = sex==1) 
# variable 0_mean 0_median 1_mean 1_median 
# 1  v1 3.027778  3 2.416667  2.0 
# 2  v2 2.638889  2 2.750000  3.0 
# 3  v3 3.027778  3 2.583333  2.5 
+0

いいです。 hadleyは 'reshape2'で複数の集約関数を適用するこの機能を削除しました。 – Ramnath

1

データを再形成しないソリューション。

f <- function(x) rbind(each(mean,median)(na.omit(x))) 
# 
# This should work but it doesn't. 
# It almost work except labelling output with function names 
# 
df.res <- ddply(df,.(unemp, sex),.fun=numcolwise(f)) 
# 
# Some workaround 
# 
df.res <- dlply(df,.(unemp, sex),.fun=numcolwise(f)) 
df.res <- cbind(attr(df.res,"split_labels"),do.call(rbind,df.res))