2

以下に生成されたものに似たデータフレームがあります。一部の個人は、特定の変数に対して複数の観測値を持ち、各変数には推定値の標準誤差 (SE) が関連付けられています。個人ごとに1行のみを含む新しいデータフレームを作成したいと思います。Kim や Bob のように複数の観測値を持つ個人については、推定値の標準誤差と新しく計算された加重平均の分散に基づいて精度加重平均を計算する必要があります。たとえば、ボブの場合、var1 の場合、これは、新しいデータフレームの var1 値を次のようにすることを意味します。

weighted.mean(c(example$var1[2], example$var1[10]), 
   c(1/example$SE1[2], 1/example$SE1[10]))

加重平均の分散であるボブの新しい SE1 は、次のようになります。

1/sum(1/example$SE1[2] + 1/example$SE1[10])

集計関数を使用してみましたが、値の算術平均を計算できましたが、私が書いた単純な関数は標準誤差を使用せず、NA を処理することもできません。

aggregate(example[,1:4], by = list(example[,5]), mean)

この問題を解決するためのコードを開発する際の助けをいただければ幸いです。サンプル データセットは次のとおりです。

set.seed(1562)
example=data.frame(rnorm(10,8,2))
colnames(example)[1]=("var1")
example$SE1=rnorm(10,2,1)
example$var2=rnorm(10,8,2)
example$SE2=rnorm(10,2,1)
example$id= 
  c ("Kim","Bob","Joe","Sam","Kim","Kim","Joe","Sara","Jeff","Bob")
example$SE1[5]=NA
example$var1[5]=NA
example$SE2[10]=NA
example$var2[10]=NA
example

       var1      SE1      var2        SE2   id
1   9.777769 2.451406  6.363250  2.2739566  Kim
2   8.753078 2.174308  6.219770  1.4978380  Bob
3   7.977356 2.107739  6.835998  2.1647437  Joe
4  11.113048 2.713242 11.091650  1.7018666  Sam
5         NA       NA 11.769884 -0.1310218  Kim
6   5.271308 1.831475  6.818854  3.0294338  Kim
7   7.770062 2.094850  6.387607  0.2272348  Joe
8   9.837612 1.956486  8.517445  3.5126378 Sara
9   4.637518 2.516896  7.173460  2.0292454 Jeff
10  9.004425 1.592312        NA         NA  Bob
4

1 に答える 1

3

plyr私はこの種の問題のパッケージが好きです。機能的にはと同等のはずaggregateですが、使い勝手がいいと思います。たくさんの例があり、ウェブサイトにはplyrのすばらしい〜20ページの紹介があります。この問題では、データはdata.frameとして始まり、もう一方の端に別のdata.frameが必要なため、次を使用します。ddply()

library(plyr)
#f1()
ddply(example, "id", summarize, 
      newMean = weighted.mean(x=var1, 1/SE1, na.rm = TRUE),
      newSE = 1/sum(1/SE1, na.rm = TRUE)
      )

どちらが返されますか:

    id newmean   newSE
1  Bob  8.8982 0.91917
2 Jeff  4.6375 2.51690
3  Joe  7.8734 1.05064
4  Kim  7.1984 1.04829
5  Sam 11.1130 2.71324
6 Sara  9.8376 1.95649

また、チェックアウトし?summarizeて?transform他のいくつかの良い背景のために。plyrより複雑なタスクに必要な場合は、無名関数を関数に渡すこともできます。

またはdata.table、一部のタスクでより高速に証明できるパッケージを使用します。

library(data.table)
dt <- data.table(example, key="id")
#f2()
dt[, list(newMean = weighted.mean(var1, 1/SE1, na.rm = TRUE),
          newSE = 1/sum(1/SE1, na.rm = TRUE)),
   by = "id"]

簡単なベンチマーク:

library(rbenchmark)
#f1 = plyr, #f2 = data.table
benchmark(f1(), f2(), 
          replications = 1000,
          order = "elapsed",
          columns = c("test", "elapsed", "relative"))

      test elapsed relative
    2 f2()   3.580   1.0000
    1 f1()   6.398   1.7872

したがってdata.table()、私の単純なラップトップでは、このデータセットの方が約1.8倍高速です。

于 2012-05-02T04:06:06.797 に答える