寻找一个非常简单的解决方案。如果满足给定条件(小于零),我想有条件地替换行中的值,并且我想对数百个(在示例中为20个)的列中执行此操作,每个列具有1.5亿行。我在第七小时尝试了我在堆栈中找到的每个解决方案,所以请不要将其标记为重复。 :-)
数据:
library(data.table)
library(dplyr)
dt <- data.table(id=c(1:1000), x=rnorm(1:1000,60,20))
使用直观的循环创建新列:
## Create new variables
for(i in 50:70) {
dt[, paste0("y", i) := i-x]
}
对单个列进行简单命令,效果很好:
dt$y60[dt$y60<0 ] <- 0
将其置于循环内部并失败:
for(i in 50:70) {
dt$y[i][dt$y[i]<0] <- 0
}
简单的DT方法应该是什么,没有运气:
for(i in 50:70) {
dt[y[i]<0, y[i] := 0]
}
尝试ifelse()
方法,没有运气:
for(i in 50:70) {
dt$y[i] <- ifelse(dt$y[i] < 0, 0, dt$y[i])
}
首先尝试创建一个列表,然后使用set()
,不要骰子:
list <- dt %>% dplyr:: select(starts_with("y"))
for(i in 50:70) {
set(dt, i, list , 0)
}
我的生命在你手中,谢谢!!
答案 0 :(得分:2)
选项1使用:=
:
dt[, (paste0("y", 50:70)) := lapply(.SD, function(x) {x[x<0] <- 0; x}), .SDcols=paste0("y", 50:70)]
选项2使用set
:
for (j in paste0("y", 50:70)) {
set(dt, dt[,which(get(j) < 0)], j, 0)
}
数据:
library(data.table)
dt <- data.table(id=c(1:1000), x=rnorm(1:1000,60,20))
for(i in 50:70) {
dt[, paste0("y", i) := i-x]
}
答案 1 :(得分:1)
如果您需要更改以y
开头的列值,则解决方案可以是mutate_at
仅对所选列执行检查:
library(dplyr)
dt %>% mutate_at(vars(starts_with("y")), funs(ifelse(.<0,0,.)))
如果你想对所有列进行检查,那么下面的行应该足够好了:
dt[dt<0] <- 0