与组或外部变量中的早期实例的差异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了与组或外部变量中的早期实例的差异相关的知识,希望对你有一定的参考价值。

我有数据

dat1 <- data.table(id=1:9,
                   group=c(1,1,2,2,2,3,3,3,3),
                   t=c(14,17,20,21,26,89,90,95,99),
                   index=c(1,2,1,2,3,1,2,3,4)
                  )

根据t的说法,我想计算index与之前值的差异。对于每个组的第一个实例,我想计算一些外部变量的差异

dat2 <- data.table(group=c(1,2,3),
                   start=c(10,15,80)
                  )

这样可以获得以下结果:

> res 
   id group  t index dif
1:  1     1 14     1   4
2:  2     1 17     2   3
3:  3     2 20     1   5
4:  4     2 21     2   1
5:  5     2 26     3   5
6:  6     3 89     1   9
7:  7     3 90     2   1
8:  8     3 95     3   5
9:  9     3 99     4   4

我试过用

dat1[ , ifelse(index == min(index), dif := t - dat2$start, dif := t - t[-1]), by = group]

但我不确定在一步中引用同一组的其他元素和外部元素。这是否可以使用data.table?

答案

可能的解决方案:

dat1[, dif := ifelse(index == min(index),
                     t - dat2$start[match(.BY, dat2$group)],
                     t - shift(t))
     , by = group][]

这使:

   id group  t index dif
1:  1     1 14     1   4
2:  2     1 17     2   3
3:  3     2 20     1   5
4:  4     2 21     2   1
5:  5     2 26     3   5
6:  6     3 89     1   9
7:  7     3 90     2   1
8:  8     3 95     3   5
9:  9     3 99     4   4

或@jogo在评论中提出的避免ifelse的变体:

dat1[, dif := t - shift(t), by = group
     ][index == 1, dif := t - dat2[group==.BY, start], by = group][]
另一答案

我会尽量避免使用ifelse并使用data.tables高效的join-capabilities:

dat1[dat2, on = "group",                                # join on group
          start := i.start][,                           # add start value
          diff  := diff(c(start[1L], t)), by = group][, # compute difference
          start := NULL]                                # remove start value

结果表是:

#   id group  t index diff
#1:  1     1 14     1    4
#2:  2     1 17     2    3
#3:  3     2 20     1    5
#4:  4     2 21     2    1
#5:  5     2 26     3    5
#6:  6     3 89     1    9
#7:  7     3 90     2    1
#8:  8     3 95     3    5
#9:  9     3 99     4    4
另一答案

您可以将shift与动态fill参数一起使用:使用.BY索引'dat2'以获得每个'组'的'start'值:

dat1[ , dif := t - shift(t, fill = dat2[group == .BY, start]), by = group]

#    id group  t index dif
# 1:  1     1 14     1   4
# 2:  2     1 17     2   3
# 3:  3     2 20     1   5
# 4:  4     2 21     2   1
# 5:  5     2 26     3   5
# 6:  6     3 89     1   9
# 7:  7     3 90     2   1
# 8:  8     3 95     3   5
# 9:  9     3 99     4   4

或者,您可以分步执行此操作。可能是品味问题,但我发现它比ifelse方式更透明。

首先是'正常'shift。然后将'index'变量添加到'dat2'并执行更新连接。

dat1[ , dif := t - shift(t), by = group]

dat2[ , index := 1]
dat1[dat2, on = .(group, index), dif := t - start]

以上是关于与组或外部变量中的早期实例的差异的主要内容,如果未能解决你的问题,请参考以下文章

R语言 | 差异显著性检验

从外部存储中检索 Relay 查询片段的变量

__init__() 内部和外部变量之间的差异

PL/SQL包(package)操作实例讲解

片段事务中的实例化错误

外部化最终实例变量