我有以下数据框:
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更快捷的方式,但我实际上并不知道如何。有人可以帮我这个吗?
答案 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