我正在尝试创建一个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?也许应用功能? 非常感谢任何和所有的帮助!
答案 0 :(得分:1)
(a == 0) * mean(b$v1) + t(t(a) * c(tapply(b$v1, b$v2, mean)))
分段运行以了解正在发生的事情。另请注意,这假定a
中的有序名称(根据OP,0和1作为条目)。
上述一堆t
的替代方法是使用mapply
(假设a
是data.frame
或data.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])
}