我有三个数据框。这里提供的示例是简化的,与我正在使用的原始数据有很大不同。
我已经定义了三个数据帧:
mata <- data.frame(matrix (data = c(1.5,2.1, 3.3, 4.5, 5.1, 6.5), nrow=3, ncol=2, byrow=T))
matb <- data.frame(matrix (data = c(4,5,6,7,8,9), nrow=3, ncol=2, byrow=T))
matc <- data.frame(matrix (data = c(8,6, 9, 7 , 4, 3), nrow = 3, ncol=2, byrow = T))
数据如下所示:
> mata
X1 X2
1 1.5 2.1
2 3.3 4.5
3 5.1 6.5
> matb
X1 X2
1 4 5
2 6 7
3 8 9
> matc
X1 X2
1 8 6
2 9 7
3 4 3
现在,我想根据mata
中使用的条件计算matb
,matc
和mata
的乘积。
我想首先检查mata
中的值是否介于0到30之间。然后我想计算一个新矩阵Q(0),Q(1).... Q(30)其中Q = mata * matb * matc
对于每一行,我想找到Q(0)到Q(30)。当我引用Q(0)时,我正在查看大于0的所有值,依此类推。
我的方法:
我创建了一个逻辑矩阵来检查mata
中的值是否落在指定范围内。
例如,我想找到大于2的值,然后找到产品。
check1 <- sapply(mata, function(x) x>2)
> check1
X1 X2
[1,] FALSE TRUE
[2,] TRUE TRUE
[3,] TRUE TRUE
矩阵检查1找到了我感兴趣的确切位置。现在,我希望在mata
中找到大于2的值的行。我最终可能需要使用rowSums
来获取一个值但不确定如何在此实现。
我使用了以下代码:
> mata[check1] * matb[check1] * matc[check1]
[1] 178.2 163.2 63.0 220.5 175.5
我想要的是当值为false时,我想将产品报告为零,其余我想用相应的值计算。
当值大于2时,预期输出如下:
63
398.7
338.7
一次检查0到30值的有效方法是什么。我想我们可以使用for循环,但我不知道该怎么做。感谢。
答案 0 :(得分:2)
为什么不简单:
matA <- mata #Copy your mata (so mata won't be changed, just the copy)
check1 <- sapply(mata, function(x) x>2)
matA[!check1]<-0 #Replace values that do not check with your criterion by 0
rowSums(matA*matb*matc) #Compute
[1] 63.0 398.7 338.7
如果您想尝试多个阈值,可以将其包装到函数中并将其应用于您的数据:
f <- function(mata,matb,matc,threshold){
matA <- mata
check1 <- sapply(mata, function(x) x>threshold)
matA[!check1]<-0
rowSums(matA*matb*matc)
}
sapply(0:30, function(x)f(mata,matb,matc,x))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27] [,28] [,29] [,30] [,31]
[1,] 111.0 111.0 63.0 0.0 0.0 0.0 0.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[2,] 398.7 398.7 398.7 398.7 220.5 0.0 0.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[3,] 338.7 338.7 338.7 338.7 338.7 338.7 175.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
答案 1 :(得分:1)
df <- data.frame(cbind(mata,matb,matc))
df2 <- apply(df,1,function(x) {
a <- ifelse(x[1] > 2, (x[1]*x[3]*x[5]),0)
b <- ifelse(x[2] > 2, (x[2]*x[4]*x[6]),0)
return(a+b)
})
编辑:使用类似于真实数据的内容
df <- data.frame(matrix (data = runif(810000,0,5), nrow = 7500, ncol=108, byrow = T))
df2 <- apply(df,1,function(x) {
a <- sapply(seq(1,35,by=2),function(y) {
ifelse(x[y] > 2, (x[y]*x[y+36]*x[y+72]),0)
})
b <- sapply(seq(2,36,by=2),function(y) {
ifelse(x[y] > 2, (x[y]*x[y+36]*x[y+72]),0)
})
return(a+b)
})