【发布时间】:2018-02-02 16:48:42
【问题描述】:
我最近问了一个关于提高代码性能的问题 (Faster method than "while" loop to find chain of infection in R)。
背景:
我正在分析存储疾病模拟模型输出的数据的大型表(300 000 - 500 000 行)。在该模型中,景观中的动物会感染其他动物。例如,在下图的示例中,动物a1 会感染景观中的每一个动物,并且感染会从一个动物转移到另一个动物,从而形成感染“链”。
在我最初的问题中,我询问如何输出与动物“d2”的“感染链”相对应的 data.frame(见下文,以绿色勾勒,以说明一个“链”)。建议解决方案适用于一种动物。
实际上,我需要计算大约 400 只动物的链,对应于所有动物的一个子集(allanimals 表)。
我已经包含了一个指向 example dataset 的链接,该链接足够大,可以玩。
这是一条链的代码,从动物 5497370 开始,请注意,我对上一个问题的列名稍作更改,并更新了代码!
代码:
allanimals <- read.csv("https://www.dropbox.com/s/0o6w29lz8yzryau/allanimals.csv?raw=1",
stringsAsFactors = FALSE)
# Here's an example animal
ExampleAnimal <- 5497370
ptm <- proc.time()
allanimals_ID <- setdiff(unique(c(allanimals$ID, allanimals$InfectingAnimal_ID)), -1)
infected <- rep(NA_integer_, length(allanimals_ID))
infected[match(allanimals$ID, allanimals_ID)] <-
match(allanimals$InfectingAnimal_ID, allanimals_ID)
path <- rep(NA_integer_, length(allanimals_ID))
curOne <- match(ExampleAnimal, allanimals_ID)
i <- 1
while (!is.na(nextOne <- infected[curOne])) {
path[i] <- curOne
i <- i + 1
curOne <- nextOne
}
chain <- allanimals[path[seq_len(i - 1)], ]
chain
proc.time() - ptm
# check it out
chain
我想为“sel.set”中的每个动物输出链:
sel.set <- allanimals %>%
filter(HexRow < 4 & Year == 130) %>%
pull("ID")
如果可能,我想将每个“链”data.frame 存储为长度 = 链数的列表。
【问题讨论】:
-
在数据生成步骤中解决这个问题似乎很简单......
-
@Gregor 你能详细说明一下吗?
-
如果可以编辑疾病模拟模型的代码,则可以在输出中包含此信息。
-
这确实是一个图论问题,您可能会在
igraph包中找到一种有效的方法。 -
@Gregor,这就是问题所在;)我只是这个轮子上的一个齿轮——我们现在不能改变输出。
标签: r performance while-loop tree