我正在尝试缩放一些数据用于绘图。某些比例可能由用户提供,其他比例可以直接从数据中提取。
因此,一组示例数据可能是:
dt1 <- data.table(Time=1:10, a=10:1, b=11:20, c=rep(11:15,2))
setkey(dt1,"Time")
绘图的范围可能是:
dt.ranges <- data.table(a=c(1,10), b=c(11,20), c=c(11,20))
我们的想法是针对每个dt1
列,通过匹配来缩放列
dt.ranges
中的名称。
我可以使用老式的数据框架式编程来做到这一点,但我想知道是否有更快/更优雅的数据。面向方法。
给出正确答案的笨重方法是:
dt2 <- data.table(
data.frame(
lapply(names(dt1)[names(dt1) %in% names(dt.ranges)],
function(nn,rt){
print(nn)
(dt1[[nn]] - min(rt[[nn]]))/(max(rt[[nn]]) - min(rt[[nn]]))
},
dt.ranges)
)
)
names(dt2) <- names(dt1)[-1]
dt2$Time <- dt1$Time
结果:
a b c Time
1: 1.0000000 0.0000000 0.0000000 1
2: 0.8888889 0.1111111 0.1111111 2
3: 0.7777778 0.2222222 0.2222222 3
4: 0.6666667 0.3333333 0.3333333 4
5: 0.5555556 0.4444444 0.4444444 5
6: 0.4444444 0.5555556 0.0000000 6
7: 0.3333333 0.6666667 0.1111111 7
8: 0.2222222 0.7777778 0.2222222 8
9: 0.1111111 0.8888889 0.3333333 9
10: 0.0000000 1.0000000 0.4444444 10
有没有人知道更好的方法?
由于
杰森
答案 0 :(得分:1)
我们从两个数据集(intersect
)中获取nm1
列名称(假设列名称的顺序相同)。将.SDcols
指定为&#39; nm1&#39;,使用Map
在两个数据集的相应列上应用该函数,并将结果分配(:=
)。
nm1 <- intersect(names(dt1), names(dt.ranges))
dt1[, (nm1) := Map(function(x,y)
(x- min(y))/(max(y)-min(y)),
.SD, dt.ranges), .SDcols= nm1]
dt1
# Time a b c
# 1: 1 1.0000000 0.0000000 0.0000000
# 2: 2 0.8888889 0.1111111 0.1111111
# 3: 3 0.7777778 0.2222222 0.2222222
# 4: 4 0.6666667 0.3333333 0.3333333
# 5: 5 0.5555556 0.4444444 0.4444444
# 6: 6 0.4444444 0.5555556 0.0000000
# 7: 7 0.3333333 0.6666667 0.1111111
# 8: 8 0.2222222 0.7777778 0.2222222
# 9: 9 0.1111111 0.8888889 0.3333333
#10: 10 0.0000000 1.0000000 0.4444444
如果列的顺序不同
dt1[, eval(nm1) := Map(function(x,y)
(x- min(y))/(max(y)-min(y)),
.SD, dt.ranges[, nm1, with=FALSE]), .SDcols= nm1]