gpt4 book ai didi

r - 数据表。快速计算每列内更改次数的方法

转载 作者:行者123 更新时间:2023-12-04 10:30:06 30 4
gpt4 key购买 nike

我想知道每个变量在每个组中变化了多少次,然后将结果添加到所有组中。

我是这样找到的:

mi[,lapply(.SD, function(x) sum(x != shift(x), 
na.rm=T) ), by = ID][,-1][,lapply(.SD,sum, na.rm=T)]

它有效,它产生了正确的结果,但在我的大型数据表中它真的很慢。我想在同一个 lapply 中执行这两个操作(或者更快更紧凑的东西),但第一个是按组完成的,第二个不是。

它可以用更简单的方式编写(也许不总是)

mi[,lapply(.SD, function(x) sum(x != shift(x), 
na.rm=T) )] [,-1]-mi[,length(unique(ID))]+1

但它仍然很慢并且需要大量内存。

还有其他想法吗?

我也尝试过使用 diffs 而不是 shift,但它变得更加困难。

这里有一个虚拟示例:

mi <- data.table(ID=rep(1:3,each=4) , year=rep(1:4, times=3),
VREP=rep(1:3,each=4) , VDI=rep(1:4, times=3), RAN=sample(12))
mi <- rbind(mi, data.table(4,1,1,1,0), use.names=F)

基准测试的大例子

mi <- as.data.table(matrix(sample(0:100,10000000,
replace=T), nrow=100000, ncol=100))
mi[,ID := rep(1:1000,each=100)]

我的问题是真正的数据集要大得多,它在内存大小的限制内,然后我将 R 配置为能够使用页面文件使用更多内存,这使得许多操作变慢了。我知道我可以拆分文件并再次加入它,但有时这会使事情变得更加困难或某些操作不可拆分。

最佳答案

您的第二种方法会产生不正确的结果,因此不是一个公平的比较点。这是 alexis_laz 建议的优化版本:

setorder(mi, ID)
setDT(Map(`!=`, mi, shift(mi)))[,
lapply(lapply(.SD, `&`, !ID), sum, na.rm = T), .SDcols = -"ID"]
# year VREP VDI RAN
#1: 9 0 9 9

在更大的样本上:

setorder(mi, ID)
microbenchmark(method1(), alexis_laz(), eddi(), times = 5)
#Unit: milliseconds
# expr min lq mean median uq max neval
# method1() 7336.1830 7510.9543 7932.0476 8150.3197 8207.2181 8455.563 5
# alexis_laz() 1350.0338 1492.3793 1509.0790 1492.5426 1577.3318 1633.107 5
# eddi() 400.3999 475.6908 494.5805 504.6163 524.2077 567.988 5

关于r - 数据表。快速计算每列内更改次数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40383921/

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