【问题标题】:Conditional join multiple tables overwriting instead of making new columns条件连接多个表覆盖而不是创建新列
【发布时间】:2019-11-05 23:45:35
【问题描述】:

我尝试加入三个数据框。困难在于我希望替换同一列中的冲突值,而不是创建新行。我尝试了 left_join 和 full_join 的不同变体,然后是过滤器。

示例数据框:

df.0 <- 
 ID SEQUENCE    FIXDT.0 FIXU.0           SEX
  3        0 2010-08-01        Spayed Female
  1        0 2011-10-01        Neutered Male
  2        0                1  Spayed Female
  5        0 2012-05-01        Neutered Male

df.1_2 <- 
 ID SEQUENCE    FIXDT.0 FIXU.0           SEX
  3        1 2010-10-01        Spayed Female
  1        1                1  Neutered Male
  4        2                1  Spayed Female
  5        1 2012-05-01        Neutered Male

df.3_6 <-
 ID SEQUENCE    FIXDT.0 FIXU.0           SEX
  6        3 2011-08-01        Neutered Male
  1        6 2012-10-01        Neutered Male
  4        4 2010-02-01        Spayed Female
  5        3 2012-05-01        Neutered Male

df.cohort <-
 ID    SEX.STATUS   BIRTH.DATE  ENROLLED.DATE
  1  Neutered Male  8/23/2010    12/11/2012
  2  Spayed Female  6/16/2011     9/11/2013
  3  Spayed Female  9/28/2011      9/6/2013 
  4  Spayed Female  6/26/2011      1/2/2013
  5  Neutered Male  4/15/2011      7/5/2012
  6  Neutered Male  5/12/2010     8/16/2011
  7  Intact Male    2/17/2011    10/25/2012

我想将这些与下面所需的输出结合在一起。我的想法是我将它们连接在一起,并用下一个加入的表中的值替换以前的值。另一件需要注意的重要事情是,如果可能的话,我希望在输出中显示 FIXDT 的日期。这意味着替换某些行但不替换其他行

df.full <-
 ID    SEX.STATUS   BIRTH.DATE  ENROLLED.DATE            Sex   FIXDT       FIXU  SEQUENCE
  1  Neutered Male  8/23/2010    12/11/2012    Neutered Male   2011-10-01              0
  2  Spayed Female  6/16/2011     9/11/2013    Spayed Female                 1         0
  3  Spayed Female  9/28/2011      9/6/2013    Spayed Female   2010-08-01              0
  4  Spayed Female  6/26/2011      1/2/2013    Spayed Female   2010-02-01              4
  5  Neutered Male  4/15/2011      7/5/2012    Neutered Male   2012-05-01              0
  6  Neutered Male  5/12/2010     8/16/2011    Neutered Male   2011-08-01              3
  7  Intact Male    2/17/2011    10/25/2012    

我知道这需要一些中间的 data.frames 并且也尝试过以这种方式解决它。我尝试使用dplyrfilter,但意识到它们最适合相等连接,我正在尝试进行不相等连接。

【问题讨论】:

  • 您是否只想通过ID 加入?

标签: r dataframe join


【解决方案1】:

对于您的加入问题,这应该可以解决问题。这意味着您想要完全替换共享列,这似乎是您正在寻找的内容

library('dplyr')

special_join <- function(x, y, by, ...) {

    shared_cols <- colnames(x) [colnames(x) %in% colnames(y) & !colnames(x) %in% by]
    x[,shared_cols] <- NULL                                                                                                        

    full_join(x, y, by, ...)

}

a <- data.frame(ID = 1:4, variable=c('a', 'b', 'c', 'd'), other_variable=4:7)                                                      
b <- data.frame(ID = 1:3, variable=c('z', 'x', 'y'))

special_join(a, b, by='ID')
#   ID other_variable variable                                                                                                       
# 1  1              4        z                                                                                                     
# 2  2              5        x
# 3  3              6        y                                                                                                      
# 4  4              7     <NA>

【讨论】:

    【解决方案2】:

    经过更多数据清理后,我尝试使用上述答案中的代码。然而,最终效果最好的是一步一步的答案。

    1) 将每个 df 与群组合并,然后子集以仅使用 distinct 保留一只狗。例如 df.1_2:

    df.1_2_join <- left_join(df.1_2, cohort, by="DOGID")
    df.1_2_join <- df.1_2_join[order(df.1_2_join$SEQUENCE),]
    df.1_2_join <- df.1_2_join %>% distinct(DOGID, .keep_all = TRUE)
    

    2) 更改以使所有对应的列名匹配。

    3) 对所有列执行full_join

    4) 按 Sequence 对完整的 data.frame 进行排序,然后再次使用 distinct 删除重复的 ID

    在此过程中,我还了解到duplicated2 是一个有用的函数,可以在数据框中写入所有重复行的列表,而不仅仅是它们的 2,3 或更多外观。我用它来检查并确保所有 ID 没有重复并且信息正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      • 2014-11-02
      • 1970-01-01
      相关资源
      最近更新 更多