繁体   English   中英

R-根据年龄杀死

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM