基于条件的三个数据帧之间的乘积

时间:2014-01-31 08:49:16

标签: r dataframe

我有三个数据框。这里提供的示例是简化的,与我正在使用的原始数据有很大不同。

我已经定义了三个数据帧:

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中使用的条件计算matbmatcmata的乘积。

我想首先检查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循环,但我不知道该怎么做。感谢。

2 个答案:

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