以另一个表中的值为条件替换一个表中的值

时间:2016-05-29 13:29:27

标签: r

我有以下数据框:

df_1 <- data.frame(f1= c(1,3,4,5,7,8), f2 = c(2,3,4,1,4,5))
df_2 <- data.frame(f1= c(0.1,0.3,0.04,0.015,0.7,0.8), f2 = c(0.02,0.13,0.4,1.4,0.04,0.5))

所以他们看起来像

> df_1
  f1 f2
1  1  2
2  3  3
3  4  4
4  5  1
5  7  4
6  8  5
> df_2
   f1   f2
1 0.100 0.02
2 0.300 0.13
3 0.040 0.40
4 0.015 1.40
5 0.700 0.04
6 0.800 0.50

我希望执行的替换是:

如果df2中的一个数字高于0.05,我希望用NA替换相应位置的df1中的数字。结果数据框df1应该看起来像

  f1 f2
1 NA  2
2 NA NA
3  4 NA
4  5 NA
5 NA  4
6 NA NA

我尝试使用for循环解决它但是应用于我的实际大表时需要很长时间。我知道可以使用data.table更快捷的方式,但我实际上并不知道如何。有人可以帮我这个吗?

2 个答案:

答案 0 :(得分:4)

你可以这样做

> df_1[df_2 > 0.05] <- NA

> df_1
  f1 f2
1 NA  2
2 NA NA
3  4 NA
4  5 NA
5 NA  4
6 NA NA

答案 1 :(得分:1)

如果性能问题,我们可以使用set中的data.table(也是帖子中提及的data.table)。使用set会很快,因为避免了[.data.table的开销。

library(data.table)
setDT(df_1)
for(j in seq_along(df_1)){
   set(df_1, i = which(df_2[[j]] > 0.05), j = j, value = NA)
 }

df_1
#   f1 f2
#1: NA  2
#2: NA NA
#3:  4 NA
#4:  5 NA
#5: NA  4
#6: NA NA

基准

set.seed(49)
df1 <- data.frame(f1 = sample(1:9, 1e7, replace=TRUE), 
                  f2 = sample(1:9, 1e7, replace=TRUE))
set.seed(24)
df2 <- data.frame(f1 = rnorm(1e7), f2 = rnorm(1e7))

akrun <- function() {DT <- as.data.table(df1)
                 for(j in seq_along(DT)){
                 set(DT, i = which(df2[[j]] > 0.05), j=j, value = NA)
                 }
                }

David <- function() {df1[df2 > 0.05] <- NA}

library(microbenchmark)
microbenchmark(akrun(), David(), unit="relative", times = 20L)
#    expr      min      lq     mean   median       uq      max neval
# akrun() 1.000000 1.00000 1.000000 1.000000 1.000000 1.000000    20
# David() 2.487825 2.65275 2.428343 2.582355 2.298318 2.126138    20