在 R 中获取 data.frame 中元素差异的最快方法
Posted
技术标签:
【中文标题】在 R 中获取 data.frame 中元素差异的最快方法【英文标题】:Fastest way to take difference of elements in a data.frame in R 【发布时间】:2020-02-26 20:51:27 【问题描述】:使用以下数据集,在不使用dplyr
、(@ 987654323@欢迎!)?
更具体地说,对于 ID
列中的每个 ID,我想将其在 value
列中的相对值与 value
列中的值相对于其他观察值之间的所有可能差异相同的ID
号码(在同一年内)。也就是说,我想要一个具有相同ID
和相同t
的对(ID
-ID2
)具有所有差异的数据框。
虚拟数据集是:
df <- data.frame(ID = rep(rep(c(1,2,3,4),3),2), ID2 = rep(c(rep(5,4), rep(6,4),
rep(7,4)),2), t = c(rep(1,12), rep(2,12)), value = runif(12) )
ID ID2 t value
1 1 5 1 0.6991799
2 2 5 1 0.0879940
3 3 5 1 0.5876535
4 4 5 1 0.2105821
5 1 6 1 0.9483806
6 2 6 1 0.5076218
7 3 6 1 0.1790157
8 4 6 1 0.5229501
9 1 7 1 0.7365285
10 2 7 1 0.5298920
11 3 7 1 0.6172215
12 4 7 1 0.3365588
13 1 1 2 0.6991799
14 2 5 2 0.0879940
15 3 5 2 0.5876535
16 4 5 2 0.2105821
17 1 6 2 0.9483806
18 2 6 2 0.5076218
19 3 6 2 0.1790157
20 4 6 2 0.5229501
21 1 7 2 0.7365285
22 2 7 2 0.5298920
23 3 7 2 0.6172215
24 4 7 2 0.3365588
应该在value
列上处理差异。然后应该像这样创建新的data.frame,其中第一行中的1(5)
指的是ID = 1
和ID2 = 5
在年份t = 1
中的行。
ID ID2 t value
1 1(5) 6 1 0.6991799 - 0.9483806
2 1(5) 7 1 0.6991799 - 0.7365285
3 1(6) 7 1 0.9483806 - 0.7365285
4 2(5) 6 1 0.0879940 - 0.5076218
2 2(5) 7 1 0.0879940 - 0.5298920
3 2(6) 7 1 0.5076218 - 0.5298920
...
【问题讨论】:
你能给我们一个预期输出的样本吗?比破译您对操作的解释更容易。 我的理解是否正确,您想计算跨 t 的不同 ID/ID2 对之间的价值差异?您想如何处理t
-组中重复的ID
s?例如,请参见第 1、5 和 9 行。它们具有相同的 ID 值。
抱歉解释不佳:我重写了问题并添加了一个示例。谢谢!
对于像runif
这样的随机数据,总是set.seed
。否则,我们无法复制您的样品。
【参考方案1】:
这应该很快。我会留下任何你不想要的列的格式和删除:
library(data.table)
setDT(df)
setkey(df, ID, t)
# self join on the keys (ID and t)
# then keep only rows where ID2 is less than the joined ID2
result = df[df, allow.cartesian = TRUE][ID2 < i.ID2]
# calculate the difference
result[, diff := value - i.value]
result
# ID ID2 t value i.ID2 i.value diff
# 1: 1 5 1 0.2468819 6 0.34515017 -0.09826830
# 2: 1 5 1 0.2468819 7 0.01068400 0.23619786
# 3: 1 6 1 0.3451502 7 0.01068400 0.33446616
# 4: 1 5 2 0.2468819 6 0.34515017 -0.09826830
# 5: 1 5 2 0.2468819 7 0.01068400 0.23619786
# 6: 1 6 2 0.3451502 7 0.01068400 0.33446616
# 7: 2 5 1 0.1749664 6 0.29682198 -0.12185559
# 8: 2 5 1 0.1749664 7 0.40023788 -0.22527149
# 9: 2 6 1 0.2968220 7 0.40023788 -0.10341590
# 10: 2 5 2 0.1749664 6 0.29682198 -0.12185559
# 11: 2 5 2 0.1749664 7 0.40023788 -0.22527149
# ...
【讨论】:
1[]
中的另一个类似选项是setorder( DT[DT, on=.(id, t, id2<id2), allow.cartesian=TRUE, nomatch=0L, .(ID=x.ID, x.ID2, ID2=i.ID2, t, value=x.value-i.value)], t, ID, ID2)[]
哈!我从这样的非 equi 自加入开始,但我有 id2 != id2
,这是不允许的。然后我改用这种方法,直到我意识到<
更合适,忘记了我可以回到非 equi 连接。谢谢!
谢谢你们!这真的有帮助!很抱歉延迟接受答案!以上是关于在 R 中获取 data.frame 中元素差异的最快方法的主要内容,如果未能解决你的问题,请参考以下文章