[英]R - kill based on age
我试图建立一种感觉应该很简单的东西,但是我找不到解决方案。 我写了一段简化的代码,试图一路解释一下。
基本上,我想每代创建一组“孩子”。 然后,将每一代的年龄加1,并在年龄> 3时删除列表条目。代码几乎可以正常工作-我认为问题与调用fl的长度有关,然后从列表中删除行有关,但是我不确定。 如果正常运行,最终结果(fl)的任何条目都不得大于3。
码:
#NUMBER OF PARENTS TO START WITH
parents <- 10
#NUMBER OF GENERATIONS TO RUN
generations <- 5
#NUMBER OF CHILDREN TO CREATE EACH GENERATION
children <- 5
#AGE TO KILL
death <- 3
pl <- list()
cl <- list()
fl <- list()
kl <- list()
#CREATE PARENTS
for (i2 in 1:parents) {
pl[[i2]] <- 0
}
fl <- pl
#START GEN LOOP
i3 <- 0
while (i3 < generations) {
i3 <- i3 + 1
#CREATE CHILDREN
for (i5 in 1:children) {
cl[[i5]] <- 0
}
#ADD CHILDREN TO FINAL LIST
fl <- c(fl, cl)
#ADD 1 TO AGE
for (i6 in 1:length(fl)) {
fl[[i6]] <- fl[[i6]] + 1
}
###PROBLEM###
#KILL BASED ON AGE
i4 <- 0
while (i4 < length(fl)) {
i4 <- i4 + 1
if (fl[[i4]] > death) {
#ADD TO KILL LIST FOR DEBUGGING
kl <- c(kl, fl[[i4]])
#REMOVE FROM fl
fl <- fl[-c(i4), drop=FALSE]
}
}
#CLOSE GEN LOOP
}
fl
谢谢!
通常,在使用R时,您希望尽可能避免循环。 它很慢,可以使用一些函数来避免它。 我认为您的原始代码无法正常工作,因为在循环中,您正在删除一个元素,然后索引将更改,然后对于下一次迭代,您最终将删除错误的元素。 我更改了您的代码,看看您的想法:
#NUMBER OF PARENTS TO START WITH
parents <- 10
#NUMBER OF GENERATIONS TO RUN
generations <- 5
#NUMBER OF CHILDREN TO CREATE EACH GENERATION
children <- 5
#AGE TO KILL
death <- 3
pl <- list()
cl <- list()
fl <- list()
kl <- list()
#CREATE PARENTS
# for (i2 in 1:parents) {
# pl[[i2]] <- 0
# }
fl <- pl <- as.list(rep(0, parents))
# fl <- pl
#START GEN LOOP
i3 <- 0
while (i3 < generations) {
i3 <- i3 + 1
#CREATE CHILDREN
# for (i5 in 1:children) {
# cl[[i5]] <- 0
# }
cl <- as.list(rep(0, children))
#ADD CHILDREN TO FINAL LIST
fl <- c(fl, cl)
#ADD 1 TO AGE
# for (i6 in 1:length(fl)) {
# fl[[i6]] <- fl[[i6]] + 1
# }
fl <- lapply(fl, function(x) x+1)
###PROBLEM###
#KILL BASED ON AGE
# i4 <- 0
# while (i4 < length(fl)) {
# i4 <- i4 + 1
# if (fl[[i4]] > death) {
#
# #ADD TO KILL LIST FOR DEBUGGING
# kl <- c(kl, fl[[i4]])
#
# #REMOVE FROM fl
# fl <- fl[-c(i4), drop=FALSE]
# }
# }
fl <- fl[fl <= death]
#CLOSE GEN LOOP
}
fl
lapply
是你的朋友
从列表中删除该元素时,并没有相应地调整i4
。 尝试这个:
###FIXED###
#KILL BASED ON AGE
i4 <- 0
while (i4 < length(fl)) {
i4 <- i4 + 1
if (fl[[i4]] > death) {
#ADD TO KILL LIST FOR DEBUGGING
kl <- c(kl, fl[[i4]])
#REMOVE FROM fl
fl <- fl[-c(i4), drop=FALSE]
i4 <- i4 - 1 # <------ added this line
}
}
同样,您的代码是相当不规范的(并且很难阅读)。 这不是代码审查,但我至少建议使用for
而不是while
...我认为您的典型R用户将对此更加满意。 我不确定lapply
实际上是否是正确的解决方案; imo失去了循环的字面共振。 但是我强烈建议编写函数,而不是仅仅写一遍循环墙。 然后你可以写一些可读的东西
life <- function(n_parents, n_children, death_age, n_generations) {
fl <- as.list(rep(0, n_parents))
for (i in 1:n_generations) {
fl <- spawn_children(fl, n_children)
fl <- lapply(fl, `+`, 1) # increment ages by 1
fl <- kill_old_people(fl, death_age)
}
fl
}
life(
n_parents = 10,
n_children = 5,
death_age = 3,
n_generations = 5
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.