R:匹配data.table列作为应用于另一个data.table的函数的函数参数

时间:2016-02-03 06:30:40

标签: r data.table

我正在尝试缩放一些数据用于绘图。某些比例可能由用户提供,其他比例可以直接从数据中提取。

因此,一组示例数据可能是:

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

有没有人知道更好的方法?

由于

杰森

1 个答案:

答案 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]