如何通过替换“a”来提高大型数据集的性能;for loop";及;如有其他",;条款
亲爱的社区: 我安静地坐在一个特定的数据集上,这个数据集相当大(nrow=约5亿)。经过一系列的数据处理,数据集基本上包括以下重要列:“ParticleId”、“flag”、“Volume”和“reduce”如何通过替换“a”来提高大型数据集的性能;for loop";及;如有其他",;条款,r,performance,if-statement,for-loop,apply,R,Performance,If Statement,For Loop,Apply,亲爱的社区: 我安静地坐在一个特定的数据集上,这个数据集相当大(nrow=约5亿)。经过一系列的数据处理,数据集基本上包括以下重要列:“ParticleId”、“flag”、“Volume”和“reduce” ParticleId是唯一的,它表示一个在时间和空间中移动的粒子 该标志指示粒子是否在特定区域内(是/否) 每个ParticleId都有一个先前的体积(注入时),如果粒子位于该特定区域的内部或外部,则该体积取决于时间 如果粒子位于特定区域内,则必须按相应的减少值减少以前的体积 我编写了
- ParticleId是唯一的,它表示一个在时间和空间中移动的粒子
- 该标志指示粒子是否在特定区域内(是/否)
- 每个ParticleId都有一个先前的体积(注入时),如果粒子位于该特定区域的内部或外部,则该体积取决于时间
- 如果粒子位于特定区域内,则必须按相应的减少值减少以前的体积
dataset <- data.frame(1:20)
dataset$ParticleId <- c(1,1,1,1,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,4)
dataset$flag <- c(T,T,T,F,T,T,F,F,T,T,T,T,T,T,F,F,F,F,T,T)
dataset$Volume <- 0.01
dataset$reduction <- c(1.21e-03,1.21e-04,1.21e-03,1.21e-06,1.21e-03,1.21e-03,1.21e-04,1.21e-03,1.21e-06,1.21e-03,1.21e-03,1.21e-04,1.21e-03,1.21e-06,1.21e-03,1.21e-03,1.21e-04,1.21e-03,1.21e-06,1.21e-03)
for(i in 2:nrow(dataset)){
if(dataset[i,]$flag == TRUE & dataset[i,]$ParticleId == dataset[i-1,]$ParticleId){
dataset[i,]$Volume <- dataset[i-1,]$Volume - dataset[i-1,]$reduction
}else{
if(dataset[i,]$flag == FALSE & dataset[i,]$ParticleId == dataset[i-1,]$ParticleId){
dataset[i,]$Volume <- dataset[i-1,]$Volume
}else{
dataset[i,]$Volume <- dataset[i,]$Volume
}
}
}
dataset这将生成所需的输出,并且应该比使用for
-循环和if.的初始方法快很多。。其他..
语句:
library(dplyr)
dataset %>%
group_by(ParticleId) %>%
mutate(Volume = Volume[1L] - cumsum(lag(reduction, default = 0L)*flag))
#Source: local data frame [20 x 5]
#Groups: ParticleId
#
# X1.20 ParticleId flag Volume reduction
#1 1 1 TRUE 0.01000000 1.21e-03
#2 2 1 TRUE 0.00879000 1.21e-04
#3 3 1 TRUE 0.00866900 1.21e-03
#4 4 1 FALSE 0.00866900 1.21e-06
#5 5 2 TRUE 0.01000000 1.21e-03
#6 6 2 TRUE 0.00879000 1.21e-03
#7 7 2 FALSE 0.00879000 1.21e-04
#8 8 2 FALSE 0.00879000 1.21e-03
#9 9 2 TRUE 0.00758000 1.21e-06
#10 10 3 TRUE 0.01000000 1.21e-03
#11 11 3 TRUE 0.00879000 1.21e-03
#12 12 4 TRUE 0.01000000 1.21e-04
#13 13 4 TRUE 0.00987900 1.21e-03
#14 14 4 TRUE 0.00866900 1.21e-06
#15 15 4 FALSE 0.00866900 1.21e-03
#16 16 4 FALSE 0.00866900 1.21e-03
#17 17 4 FALSE 0.00866900 1.21e-04
#18 18 4 FALSE 0.00866900 1.21e-03
#19 19 4 TRUE 0.00745900 1.21e-06
#20 20 4 TRUE 0.00745779 1.21e-03
它的作用是:
- 以数据“数据集”为例
- 按ParticleId对数据进行分组(然后对每组执行以下操作)
mutate
用于修改/添加数据列。在本例中,我们修改现有列“Volume”。我们取每组体积的第一个元素(Volume[1L]
),并从该值中减去reduction*flag
的累积和。因为我们将reduce
与标志
相乘,这是一个逻辑列,所以只要标志
为真
,reduce就乘以1,只要标志
为假
,reduce就乘以0。这意味着,如果flag
为FALSE
,我们将从Volume列中减去0(无)(即保持原样)。此外,我们使用lag(Volume,default=0)
,因为我们希望在每一行中减去前一行(lag)中出现的减少值。default=0
确保,如果一个组中没有前一行,即我们在一个组的第一行上操作,则前一个减少值假定为0,因此,我们不会从第一行体积值中减去任何东西
- 如果您想知道为什么我在数字后面使用L(如在
default=0L
):它用于表示整数
——这些值使用更少的内存,因此可以帮助代码加快一点速度,因为您处理的数据量相当大
我尝试在data.table中使用相同的代码(可能更快一点):
我认为在最新版本的data.table(1.9.5)中,您可以使用shift
创建滞后减少
该方法与这里的dplyr解决方案基本相同。但在开始之前,我们使用setDT()
将data.frame转换为data.table
对象,并使用setkey()
设置键。除数据外,其余数据非常相似。表通过引用更新数据(使用:=
),而不是滞后(…,默认值=0)
我们使用c(0,head(reduce,-1))
真是天才。谢谢!我用我的40k子集尝试了你的代码,结果在1-2秒内完成了。一旦我以同样的方式操作了孔数据集,我将尝试使用改进的孔数据集(data.table)。我真的很感激,尽管我能大致理解您是如何使用这些函数的。你能推荐一些文献来学习这个复杂的组合吗?我会在我的答案中添加一个简短的解释。通常,您可以通过阅读CRAN(和)上的文档来了解这些包及其功能。对于dplyr,您还可以查看和。@Herbert对于数据表
,我们正在创建更详细的渐晕图。新的应该让你开始。其他小插曲的链接可用。新的小插曲也将在那里更新。HTH.@docendo discimus感谢您提供的额外信息-这些信息帮助很大。阿伦:谢谢你的评论。我来看看推荐的文献。我希望这些答案也能帮助其他人,因为我无法通过密集的网络搜索找到类似的解决方案。
library(data.table)
setkey(setDT(dataset), ParticleId)[,
Volume:=Volume[1L]-cumsum(c(0L, head(reduction, -1L))*flag), ParticleId]