首页 > 解决方案 > 将来自变量名称向量的 Inf/-Inf 值替换为来自具有类似名称的变量向量 (substr/grep/gsub) 的值

问题描述

我目前很难编写一些有效的代码。我有一个变量向量(med.vars),这些变量由年内全球中位数转换。有时全局中位数为 0,这会创建Inf/-Inf我想用预先转换的变量值 (vars) 替换的值。我无法弄清楚如何使用某种类型的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]结果data.table为:

   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

感谢您的时间

标签: rdata.table

解决方案


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

推荐阅读