gpt4 book ai didi

r - 在 data.table 中获取列差异

转载 作者:行者123 更新时间:2023-12-04 11:37:38 26 4
gpt4 key购买 nike

如何使用 data.table 语法生成一个 data.table ,其中每列包含原始 data.table 的列和下一列之间的差异?

示例:我有一个 data.table ,其中每一行都是一个组,每一列都是第 0 年、第 1 年、第 2 年等之后的幸存人口。例如:

pop <- data.table(group_id = c(1, 2, 3), 
N = c(4588L, 4589L, 4589L),
N_surv_1 = c(4213, 4243, 4264),
N_surv_2 = c(3703, 3766, 3820),
N_surv_3 = c(2953, 3054, 3159) )
# group_id N N_surv_1 N_surv_2 N_surv_3
# 1 4588 4213 3703 2953
# 2 4589 4243 3766 3054
# 3 4589 4264 3820 3159

(数据类型不同,因为 N 是一个真正的整数计数,而 N_surv_1 等是可能是小数的投影。)

我做了什么:使用基础 diff和矩阵转置,我们可以:
diff <- data.table(t(diff(t(as.matrix(pop[,-1,with=FALSE])))))
setnames(diff, paste0("deaths_",1:ncol(diff)))
cbind(group_id = pop[,group_id],diff)
# produces desired output:
# group_id deaths_1 deaths_2 deaths_3
# 1 -375 -510 -750
# 2 -346 -477 -712
# 3 -325 -444 -661

我知道我可以使用 base diffmelt.data.table 生成的单个列上的组,所以这可行,但并不漂亮:
melt(pop, 
id.vars = "group_id"
)[order(group_id)][, setNames(as.list(diff(value)),
paste0("deaths_",1:(ncol(pop)-2)) ),
keyby = group_id]

这是执行此操作的最常见的 data.table 方式,还是有办法将其作为 data.table 中的多列操作来执行?

最佳答案

好吧,您可以减去子集:

ncols = grep("^N(_surv_[0-9]+)?", names(pop), value=TRUE)
pop[, Map(
`-`,
utils:::tail.default(.SD, -1),
utils:::head.default(.SD, -1)
), .SDcols=ncols]

# N_surv_1 N_surv_2 N_surv_3
# 1: -375 -510 -750
# 2: -346 -477 -712
# 3: -325 -444 -661

您可以使用 := 将这些值分配给新列.我不知道为什么 tailhead没有更容易获得......正如@akrun所指出的,您可以使用 with=FALSE相反,如 pop[, .SD[, -1, with=FALSE] - .SD[, -ncol(.SD), with=FALSE], .SDcols=ncols] .

无论如何,与简单的 reshape 相比,这相当复杂:
melt(pop, id="group_id")[, tail(value, -1) - head(value, -1), by=group_id]
# group_id V1
# 1: 1 -375
# 2: 1 -510
# 3: 1 -750
# 4: 2 -346
# 5: 2 -477
# 6: 2 -712
# 7: 3 -325
# 8: 3 -444
# 9: 3 -661

关于r - 在 data.table 中获取列差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39001855/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com