【问题标题】:Run loop until condition is no longer found in R运行循环,直到在 R 中不再找到条件
【发布时间】:2021-07-20 20:33:26
【问题描述】:

我对 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),] 是行不通的,因为有时后代的出生日期错误,然后被放在父母面前。

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

【问题讨论】:

  • 从好的方面来说,如果 {mother/father} -> child 的关系可以被认为是可靠的,那么您已经测试了您的数据质量,这可能有助于估算后代的出生日期,所以也许你想估算而不是排除这些错误的条目。我想我是说使用 Bornbefore 来索引不良数据并制定合理的规则来更改它们以符合谱系并将它们标记为估算。
  • 从概念上讲,我想知道您所做的是否明智。潜在的理论似乎是,如果你在父母之前出生,那么你的出生日期是错误的。但是如果他们他们的父母之前出生呢?那么他们的生日也应该是NA。那么,您希望按哪个顺序应用此逻辑?
  • @dash2 我明白你在说什么。 aprents 有时比父母早出生的情况也出现在我的数据集中。但是我正在使用 R 来“清理”我的数据集,然后通过一个程序运行它,该程序将为我计算很多东西(这将让我永远在 R 中)。它所做的其中一件事是根据他们父母的生日和他们后代的生日来估计出生日期未知的个人的出生日期。就顺序而言,我认为是从第一代(最老一代)的个体开始,然后通过谱系向下走
  • 这是有道理的,如果您知道代数,这是限制您正在执行的数据库连接大小的自然方法

标签: r loops sorting


【解决方案1】:

加入是自然的方式:

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]

【讨论】:

  • 注意:大数据的连接可能会很慢。如果您可以以某种方式将数据库拆分为单独的沿袭,那可能会有所帮助。或者无论如何它可能已经足够快了。或者您可以尝试使用 data.table 来加快速度。
【解决方案2】:

这可能不是最优雅的解决方案,但应该可以。它使用 base R 和 dplyr 的组合:

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))

library(dplyr)

m <- m %>% rename(dad_id = dad,
                  mom_id = mom)


dad <- m[,c("id", "yr")]
dad <- dad %>% rename(dad_id = id,
                      dad_yr = yr)

mom <- m[,c("id", "yr")]
mom <- mom %>% rename(mom_id = id,
                      mom_yr = yr)

m_new <- m %>% 
  left_join(dad, by = "dad_id") %>%
  left_join(mom, by = "mom_id")

m_new$bornbefore <- ifelse((m_new$yr <= m_new$dad_yr | m_new$yr <= m_new$mom_yr), TRUE, FALSE)
m_new$yr <- ifelse(m_new$bornbefore == TRUE, NA, m_new$yr)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2014-05-12
    • 2016-06-18
    • 2022-11-23
    • 2018-11-09
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多