基于第二个数据帧中的值来过滤数据帧

我有2个数据框:

at1 = data.frame(ID = c("A", "B", "C", "D", "E"), Sample1 = rnorm(5, 50000, 2500),
      Sample2 = rnorm(5, 50000, 2500), Sample3 = rnorm(5, 50000, 2500),
      row.names = "ID")

  Sample1  Sample2  Sample3
A 52626.55 51924.51 50919.90
B 51430.51 49100.38 51005.92
C 50038.27 52254.73 50014.78
D 48644.46 53926.53 51590.05
E 46462.01 45097.48 50963.39

bt1 = data.frame(ID = c("A", "B", "C", "D", "E"), Sample1 = c(0,1,1,1,1),
      Sample2 = c(0,0,0,1,0), Sample3 = c(1,0,1,1,0), 
      row.names = "ID")

   Sample1 Sample2 Sample3
A       0       0       1
B       1       0       0
C       1       0       1
D       1       1       1
E       1       0       0

我想基于bt1(0或1)中相应单元格中的值来过滤at1中的每个单元格,并将结果存储在新的数据帧ct1中.例如,如果bt1 [1,“Sample1”] = 1,则ct1 [1,“Sample1”] = at1 [1,“Sample1”].如果bt1 [1,“Sample1”] = 0,则ct1 [1,“Sample1”] = 0.我的原始数据帧有超过100列,超过30,000行.

我想知道是否有一种比写入if循环更简单的方法(例如使用“apply”?).

最佳答案
这是一个data.table解决方案,另一个是简单化的解决方案

请注意,我已经将ID作为data.frame中的特定列,而不是row.names
意识形态和理性原因

>一个data.table没有rownames
>我认为将它们作为数据的一部分来考虑是比较容易的

library(data.table)
library(reshape2)

bt1 <- data.frame(ID = c("A", "B", "C", "D", "E"), Sample1 = c(0,1,1,1,1),
   Sample2 = c(0,0,0,1,0), Sample3 = c(1,0,1,1,0))

at1 <- data.frame(ID = c("A", "B", "C", "D", "E"), Sample1 = rnorm(5, 50000, 2500),
  Sample2 = rnorm(5, 50000, 2500), Sample3 = rnorm(5, 50000, 2500))

# place in long form
at_long <- data.table(melt(at1, id.var = 1))
bt_long <- data.table(melt(bt1, value.name = 'bt_value', id.var = 1))
# set keys for easy merging with data.tabl
setkeyv(at_long, c('ID','variable'))
setkeyv(bt_long, c('ID','variable'))
# merge
combined <- at_long[bt_long]
# set those where 'bt_value == 0' as 0
set(combined, which(combined[['bt_value']]==0), 'value',0)
# or (using the fact that the `bt` data is only 0 or 1
combined[value := value * bt_value]
# then reshape to wide format
dcast(combined, ID~variable, value.var = 'value')
##   ID  Sample1  Sample2  Sample3
## 1  A     0.00     0.00 50115.24
## 2  B 50173.16     0.00     0.00
## 3  C 48216.31     0.00 51952.30
## 4  D 52387.53 50889.95 44043.66
## 5  E 50982.56     0.00     0.00

第二个简单的方法

如果您知道bt1和at1(您的数据集)中的行顺序相同,则可以简单地将数据的相应组件乘以(*以元素为单位)

sample_cols <- paste0('Sample',1:3)
at1[,sample_cols] * bt1[,sample_cols]

##    Sample1  Sample2  Sample3
## 1     0.00     0.00 50115.24
## 2 50173.16     0.00     0.00
## 3 48216.31     0.00 51952.30
## 4 52387.53 50889.95 44043.66
## 5 50982.56     0.00     0.00

您可以从at1或bt1将其绑定到ID,或者如果将ID保留为row.names,则row.names将持续存在.

转载注明原文:基于第二个数据帧中的值来过滤数据帧 - 代码日志