3

5 つの変数を含むデータフレームがあります。そのうちの 2 つはメトリック測定値であり、そのうちの 3 つは係数として格納されたグループを含んでいます。このデータフレームをループ内で 3 回、異なるグループごとにサブセット化し、グループごとの各メトリック測定値の平均を計算しようとしました。結果は、新しいリスト内の新しいデータフレームとして保存できます。今のところ私は使用subsetldplyplyrパッケージから。単一のサブセットは問題ありませんが、ループからの結果をベクトルに格納しようとすると、number of items to replace is not a multiple of replacement length. サンプルコードは以下にあります。どんな助けでも大歓迎です!

df<-data.frame(a=c(1:5),b=c(21:25),group1=c("a","b","a","a","b"),group2=c("b","a","c","b","c"),group3=c("a","b","c","d","c"))

# single subset
llply(subset(df,group1=="a")[1:2],mean)

# subset for all groups
# create grouplist
grouplist<-colnames(df[3:5])
# create vector to store results
output.vector<-vector()

# create loop
for (i in grouplist)output.vector[i]<-ldply(subset(df,grouplist=="a")[1:2],mean)

output.vector

Warning messages:
1: In output.vector[i] <- ldply(subset(df, grouplist == "a")[1:2],  :
  number of items to replace is not a multiple of replacement length

したがって、リスト内の 1 つの項目の出力は次のようになります。

output.vector$group1
         |a|    | b|
|a|     |2.67|  |3.5|
|b|     |22.7|  |23.5|

output.vector$group2
     |a|    | b|    |c|
|a|  |2|    |2.5|   |4|
|b|  |22|   |22.5|  |24|

output.vector$group3
     |a|     |b|    |c|    |d|
|a|  |1|     |2|    |4|    |4|
|b|  |21|    |22|   |24|   |14|
4

3 に答える 3

3

byと を使用しcolMeans、グループ列をループする基本パッケージの別のオプション:

 id.group <- grepl('group',colnames(df))
 lapply(df[,id.group],
       function(x){
         res <- by(df[,!id.group],x,colMeans)
         do.call(rbind,res)
       })
$group1
         a        b
a 2.666667 22.66667
b 3.500000 23.50000

$group2
    a    b
a 2.0 22.0
b 2.5 22.5
c 4.0 24.0

$group3
  a  b
a 1 21
b 2 22
c 4 24
d 4 24

いくつかのベンチマークを追加して編集

library(microbenchmark)
microbenchmark(ag(),dr(),an())

Unit: milliseconds
 expr       min        lq    median        uq      max neval
 ag()  4.717987  4.936251  5.072595  5.394017 27.13639   100
 dr() 14.676580 15.244331 15.689392 16.252781 43.76198   100
 an() 14.691750 15.159945 15.625107 16.312705 46.01326   100

agstudy ソリューションが勝者のようです。他の 2 つのソリューションよりも 3 倍高速です。

ここで使用される関数:

ag <- function(){
id.group <- grepl('group',colnames(df))
lapply(df[,id.group],
       function(x){
         res <- by(df[,!id.group],x,colMeans)
         do.call(rbind,res)
       })
}
dr <- function(){

grouplist<-colnames(df[3:5])
lapply(grouplist, function(n) 
  daply(df, n, function(d) colMeans(d[, 1:2])))
}


an <- function(){
temp <- melt(df, id.vars=1:2)
setNames(
  lapply(unique(temp$variable), function(x) {
    aggregate(. ~ value, temp[temp$variable == x, c(1, 2, 4)], mean)
  }), unique(temp$variable))
}
于 2013-04-19T16:49:30.993 に答える
2

これは、lapplyとパッケージの組み合わせを使用して実行できます。daplyplyr

grouplist<-colnames(df[3:5])
lapply(grouplist, function(n) daply(df, n, function(d) colMeans(d[, 1:2])))

# [[1]]
#       
# group1        a        b
#      a 2.666667 22.66667
#      b 3.500000 23.50000
# 
# [[2]]
#       
# group2   a    b
#      a 2.0 22.0
#      b 2.5 22.5
#      c 4.0 24.0
# 
# [[3]]
#       
# group3 a  b
#      a 1 21
#      b 2 22
#      c 4 24
#      d 4 24
于 2013-04-19T16:45:54.613 に答える