在没有for循环的情况下,以另一个df为条件创建data.frame

时间:2013-07-17 19:41:05

标签: r for-loop dataframe conditional

我正在尝试创建一个data.frame,它根据引用data.frame的值取不同的值。我只知道如何使用“for循环”执行此操作,但建议避免R中的循环...并且我的实际数据有~500,000行x~200列。

a <- as.data.frame(matrix(rbinom(10,1,0.5),5,2,dimnames=list(c(1:5),c("a","b"))))
b <- data.frame(v1=c(2,10,12,5,11,3,4,14,2,13),v2=c("a","b","b","a","b","a","a","b","a","b"))
c <- as.data.frame(matrix(0,5,2))

for (i in 1:5){
  for(j in 1:2){
    if(a[i,j]==1){
      c[i,j] <- mean(b$v1[b$v2==colnames(a)[j]])
    } else {
      c[i,j]= mean(b$v1)
    }}}
c 

我根据每个单元格中的值以及data.frame“a”的相应列名创建data.frame“c”。 还有另一种方法吗?索引?使用data.table?也许应用功能? 非常感谢任何和所有的帮助!

2 个答案:

答案 0 :(得分:1)

(a == 0) * mean(b$v1) + t(t(a) * c(tapply(b$v1, b$v2, mean)))

分段运行以了解正在发生的事情。另请注意,这假定a中的有序名称(根据OP,0和1作为条目)。

上述一堆t的替代方法是使用mapply(假设adata.framedata.table而不是matrix {1}},而上述内容并不在意):

(a == 0) * mean(b$v1) + mapply(`*`, a, tapply(b$v1, b$v2, mean))

答案 1 :(得分:1)

#subsetting a matrix is faster
res <- as.matrix(a)

#calculate fill-in values outside the loop
in1 <- mean(b$v1)
in2 <- sapply(colnames(a),function(i) mean(b$v1[b$v2==i]))

#loop over columns and use a vectorized approach 
for (i in seq_len(ncol(res))) {
  res[,i] <- ifelse(res[,i]==0, in1, in2[i])
}