我目前很困惑地编写一些有效的代码。我有一个变量向量(med.vars),这些变量被年内全球中位数转化。有时全局中位数为0,这会创建logger
值,我想用预先转换的变量值(vars)代替。我无法弄清楚如何使用某些类型的%(name)s
函数或带有Inf/-Inf
,data.table 'dat[,:=lapply(.SD), .SDcols=med.vars]
等的for循环来有效地做到这一点。
get()
实际上,这些向量是我用noquotes()
从dat<-data.table(v1=c(2,10,7),v2=c(5,6,5),v3=c(10,15,20),v1.med=c(1,Inf,5),v2.med=c(5,6,5),v3.med=c(-Inf,2,3))
vars<-c("v1","v2","v3")
med.vars<-c("v1.med","v2.med","v3.med")
v1 v2 v3 v1.med v2.med v3.med
1: 2 5 10 1 5 -Inf
2: 10 6 15 Inf 6 2
3: 7 5 20 5 5 3
中提取的50多个变量,并使用names(dat)
创建了预先转换的变量名的第二向量。
我想高效地执行
grep()
对于每个元素gsub(".med","",med.vars)
及其对应的元素dat[v1.med==Inf | v1.med==-Inf, v1.med:=v1]
dat[v3.med==Inf | v3.med==-Inf, v3.med:=v3]
,这样得到的med.vars[i]
为:
vars[i]
谢谢您的时间
答案 0 :(得分:3)
OP提到效率,所以也许改用长期形式。然后可以使用标准语法:
DT = melt(dat, meas=list(vars, med.vars), value.name=c("var", "med"))
DT[!is.finite(med), med := sign(med)*var]
variable var med
1: 1 2 1
2: 1 10 10
3: 1 7 5
4: 2 5 5
5: 2 6 6
6: 2 5 5
7: 3 10 -10
8: 3 15 2
9: 3 20 3
答案 1 :(得分:2)
由于这些是对应的列,我们可以使用Map
dat[, (med.vars) := Map(function(x, y) ifelse(is.finite(y), y,
x * sign(y)), .SD[, vars, with = FALSE],
.SD[, med.vars, with = FALSE])]
dat
# v1 v2 v3 v1.med v2.med v3.med
#1: 2 5 10 1 5 -10
#2: 10 6 15 10 6 2
#3: 7 5 20 5 5 3
或者另一个选择是set
,方法是使用for
循环遍历各列
for(j in seq_along(vars)) {
i1 <- !is.finite(dat[[med.vars[j]]])
v1 <- dat[[vars[j]]]
v2 <- dat[[med.vars[j]]]
set(dat, i = which(i1), j = med.vars[j], value = sign(v2[i1]) * v1[i1])
}
这也可以在base R
上(在data.frame
上完成)
i1 <- !sapply(dat[med.vars], is.finite)
dat[med.vars][i1] <- dat[vars][i1] * sign(dat[med.vars][i1])