首页 > 解决方案 > 运行循环,直到在 R 中不再找到条件

问题描述

我对 R 并不陌生,但仍然是一个新手和学习者(因此非常欢迎解释)。我有一个完全打乱的谱系数据集(165000 多个条目)。

我的目标:确保没有人的生日早于父母。如果是这种情况,那么我想将该生日更改为 NA(我稍后会将其更改为空白)。下面是与我的数据集类似的示例。(也有生日不详的人)

m <- data.frame(id =  c(1 , 4, 7,11,15, 2, 3, 5,20,17, 6, 8,19,14,13, 9,12,10,16,18),
                dad = c(NA,NA,NA, 4, 4,NA,NA,NA,18,7 ,NA,NA,14,7 ,5 ,NA, 5, 3, 9, 7),
                mom = c(NA,NA,NA,2 ,8 ,NA,NA,NA,16,10,NA,NA,13, 6, 2,NA, 1, 1, 6,11),
                yr = c(1977,1976,1977,1981,1984,1975,1976,NA,1989,1985,1978,1978,1988,NA,
                       1982,1978,1982,1980,1984,1985))

m1 <- transform(m, bornbefore = yr <= yr[match(mom, id)] | yr <= yr[match(dad, id)])
m2 <- transform(m1, yr_new = ifelse(bornbefore == TRUE, NA, yr)

仅运行此代码一次,仍然给我留下了一些 Bornbefore == TRUE。所以我想知道是否有办法使用任何循环函数来完成这项工作(应用系列、while 循环等)?我在 loo[ 功能中迷失了方向,因此非常感谢您的帮助。

另外,我想知道它是否有助于对数据进行排序,以便父母在数据集中的后代之前?简单地使用m[order(m$yr),]是行不通的,因为有时后代的出生日期错误,然后被放在父母面前。

感谢您提前提供任何帮助,我希望我的问题很清楚。

标签: rloopssorting

解决方案


联接是自然的方式:

library(dplyr)

m_dad <- left_join(m, m, by = c("dad" = "id"))
m_dad <- mutate(m_dad, yr.x = ifelse(yr.x >= yr.y, yr.x, NA)) 
m[] <- m_dad[1:4] # a nice trick to keep column names from m

m_mom <- left_join(m, m, by = c("mom" = "id"))
m_mom <- mutate(m_mom, yr.x = ifelse(yr.x >= yr.y, yr.x, NA)) 
m[] <- m_mom[1:4]

推荐阅读