1

3 つのデータ フレームのリストがあり、行がグループ化変数 (g1) の各値と g1 変数による 6 つの変数の平均で構成される 3 つのデータ フレームの別のリストを生成したいと考えています。ねじれは、対応するダミー変数の値が 1 に等しい場合にのみ、3 つの連続変数の平均を計算したいということです。

再現可能な例:

    a <- data.frame(c("fj","fj","fj","a","fj","a","g","g","g","g"),c(1,1,1,1,0,0,0,1,0,0),c(0,0,1,0,1,0,0,1,0,1),c(0,0,0,1,0,0,1,1,0,0),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)))
b <- data.frame(c("fj","a","fj","a","fj","fj","fj","g","g","g"),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)))
c <- data.frame(c("fj","fj","fj","a","fj","a","g","g","g","g"),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 0, max = 2)),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)),floor(runif(10, min = 10, max = 200)))
u <- list(a,b,c)
u <- lapply(u, setNames, nm = c('g1','dummy1','dummy2','dummy3','contin1','contin2','contin3'))

u[[1]]

> u
[[1]]
   g1 dummy1 dummy2 dummy3  contin1 contin2 contin3
1  fj      1      0      0       199      18      61
2  fj      1      0      0        91     158      28
3  fj      1      1      0       147      67     190
4   a      1      0      1       181     105      22
5  fj      0      1      0        14      16     156
6   a      0      0      0       178      14      98
7   g      0      0      1       116      97      30
8   g      1      1      1        48      31     144
9   g      0      0      0        60      21     112
10  g      0      1      0        95     145     199

contin1の平均はdummy1=1のときだけ、contin2の平均はdummy2=1のときだけ、contin3の平均はdummy3=1のときだけ計算したい

最初のリストの出力 I WANT:

> rates
[[1]]
  x[, 1]   V1  V2  V3 x[, 1] x[, 6] x[, 1] x[, 7] x[, 1] x[, 8]
1      a 0.50 0.0 0.5      a 181         a  NA         a  22
2     fj 0.75 0.5 0.0     fj 145.67     fj  41.5      fj  NA
3      g 0.25 0.5 0.5      g  48         g  88         g  87

私が試したこと:

rates <- lapply(u, function(x) {
    cbind(aggregate(cbind(x[,2],x[,3],x[,4]) ~ x[,1], FUN = mean, na.action = NULL),
    aggregate(x[,6] ~ x[,1], FUN = mean, na.action = NULL, subset = (x[,2] == 1)),
    aggregate(x[,7] ~ x[,1], FUN = mean, na.action = NULL, subset = (x[,3] == 1)),
    aggregate(x[,8] ~ x[,1], FUN = mean, na.action = NULL, subset = (x[,4] == 1)))
    })
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 3, 2

行数が異なるオブジェクトを cbind しようとすると cbind が失敗するため、このエラーは cbind から発生していることを理解しています。(列 x[, 6] には 3 つの行がありますが、x[, 7] と x[, 8] には 2 つの行があります。) グループ化変数ごとに 1 つの行を保持する集計方法があることを望んでいたと思います。同じ数の行があり、cbind が機能することを確認しました。おそらく、これは R のドキュメントでは不可能ですか?: 「by 変数のいずれかに値が欠落している行は、結果から除外されます。」

集計のドキュメントを慎重に読みました。次の 2 つの投稿は同様の問題に対処していますが、データの異なるサブセットを使用して平均を計算していません。

R: グループのサブセットの平均を計算、R のデータ フレームのリストから平均を計算します。

どんな提案でも大歓迎です。

4

2 に答える 2

1

別のオプションは、フォーマットを「ワイド」から「ロング」に変更し、「平均」値を取得した後に「ワイド」に再変換することです。複数の値の列の場合、これはieの devel バージョンから で可能meltになりました。からインストールできます。(@akhmed の投稿と同じデータセットを使用)。dcastdata.tablev1.9.5here

melt列 ('dummy' および 'contin') のインデックスをリストとして指定することにより、リスト ('u') 内のデータセットを取得できmeasure.varsます。value.vars を 'dummyMean' および 'continMean' として指定することにより 、'g1' および 'variable' ('melt' から作成) でグループ化された 'dummy' および 'contin' 列の平均を取得しますdcastlongwide

 res <-  lapply(u, function(x) {
   x1 <- melt(setDT(x), measure.vars=list(2:4,5:7),
                        value.name=c('dummy', 'contin'))
   x2 <- x1[, list(dummyMean = mean(dummy, na.rm=TRUE),
             continMean = mean(contin[dummy==1], na.rm=TRUE)), 
                           by=list(g1, variable)]

  dcast(x2, g1~variable, value.var=c('dummyMean', 'continMean'))})

 res[[1]]
 #   g1 1_dummyMean 2_dummyMean 3_dummyMean 1_continMean 2_continMean
 #1:  a        0.50         0.0         0.5    128.00000          NaN
 #2: fj        0.75         0.5         0.0     94.66667           64
 #3:  g        0.25         0.5         0.5     54.00000           57
 #    3_continMean
 #1:           17
 #2:          NaN
 #3:          146

またはbase Rを使用したオプションMap。'dummy' 列と 'contin' 列をサブセット化する関数 'fdummy' と 'fcontin' を作成しました。'u' ( lapply(...)) をループします。を使用Mapして、'g1' 列でグループ化された 'dummy' および 'contin' の対応する列を取得し、'dummy==1' を使用して 'dummy' および 'contin' 列のmean結果を取得します。meantapplycbind

 fdummy <- function(x) x[grep('dummy', names(x))]
 fcontin <- function(x) x[grep('contin', names(x))]
 res2 <- lapply(u, function(x) {
        do.call(cbind.data.frame,
           Map(function(x,y,z) cbind(tapply(x,z, FUN=mean), 
                              tapply(y[x==1],z[x==1], FUN=mean)), 
                             fdummy(x), fcontin(x), x['g1']))})


lapply(res2, setNames, c(rbind(paste0('dummyMean', 1:3), 
                    paste0('continMean',1:3))))[[1]]
#    dummyMean1 continMean1 dummyMean2 continMean2 dummyMean3 continMean3
#a        0.50   128.00000        0.0          NA        0.5          17
#fj       0.75    94.66667        0.5          64        0.0          NA
#g        0.25    54.00000        0.5          57        0.5         146
于 2015-03-23T04:28:21.383 に答える