r - 在循环中对数据进行子集化并将结果写入列表

标签 r loops plyr subset

我有包含五个变量的数据框。其中两个是公制测量,其中三个包含存储为因子的组。我尝试通过不同的组在一个循环中对该数据框进行三次子集化,并计算每组每个指标测量的平均值。结果可以存储为新列表中的新数据帧。现在,我使用了 plyr 包中的 subsetldply。单个子集没有问题,但是当我尝试将循环的结果存储在向量中时,我收到一条警告消息,指出 number of items to replace is not multiple of items to replace。示例代码可以在下面找到。任何帮助将不胜感激!

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

因此列表中的一项的输出将如下所示:

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|

最佳答案

基础包中的另一个选项使用 bycolMeans ,并循环遍历组列:

 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))
}

关于r - 在循环中对数据进行子集化并将结果写入列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16109178/

相关文章:

r - 用尾随行值乘以增长率填充 NA 值?

r - 时间序列面板数据的普遍滞后

r - 聚合 - R 中的 na.omit 和 na.pass 因子(按因子分组)?

javascript - 如何动态定义和调用 jQuery 函数

Java 循环 CSV 读取

r - plyr 中的计数不起作用,返回 "wrong result size (3), expected 8 or 1"

R-计算从顶行到底行的数据框列的平均值

r - R 中的凹坑 dPlot 颜色 x 轴条值

java - 循环和重新分配值

r - 在 R 中按组向数据帧添加索引(或计数器)