【问题标题】:Set a variable to NA if other variables are duplicates in R如果其他变量在 R 中重复,则将变量设置为 NA
【发布时间】:2019-08-27 20:56:39
【问题描述】:

根据给药途径,我有以下包含药物代码的数据框:

code <- data.frame(inn = c("ibuprofen", "ibuprofen", "ibuprofen", "fusidic acid", "fusidic acid"),
                   route = c("unknown", "unknown", "unknown", "oral", "topical"),
                   atc = c("R02AX02", "G02CC01", "M01AE01", "J01XC01", "D06AX01"))

           inn   route     atc
1    ibuprofen unknown R02AX02
2    ibuprofen unknown G02CC01
3    ibuprofen unknown M01AE01
4 fusidic acid    oral J01XC01
5 fusidic acid topical D06AX01

另一个包含患者治疗和事件:

event <- data.frame(id = c(1, 1, 2),
                    inn = c("ibuprofen", "fusidic acid", "fusidic acid"),
                    route = c("unknown", "oral", "topical"),
                    event = c(TRUE, FALSE, TRUE))

  id          inn   route event
1  1    ibuprofen unknown  TRUE
2  1 fusidic acid    oral FALSE
3  2 fusidic acid topical  TRUE

我需要合并这些数据框得到以下结果:

           inn   route id event     atc
1 fusidic acid    oral  1 FALSE J01XC01
2 fusidic acid topical  2  TRUE D06AX01
3    ibuprofen unknown  1  TRUE NA

我没有通过简单的merge 得到这个结果:

merge(x = event,
      y = code)

           inn   route id event     atc
1 fusidic acid    oral  1 FALSE J01XC01
2 fusidic acid topical  2  TRUE D06AX01
3    ibuprofen unknown  1  TRUE R02AX02
4    ibuprofen unknown  1  TRUE G02CC01
5    ibuprofen unknown  1  TRUE M01AE01

我想到了两个解决方案,但我没有设法实施:

  • 修改merge之前的code数据框,如果atc一组innroute有不同的atc,则将atc设置为NA(这似乎更合适)李>
  • 如果innrouteid一组有不同的atc,则修改merge的结果,将atc设置为NA

如何在基础 R 中做到这一点?还有其他更好的方法吗?我在一个限制性的环境中工作,我只能访问基础 R。

【问题讨论】:

    标签: r merge duplicates unique na


    【解决方案1】:

    案例2的代码:

    code$inn_route <- paste0(code$inn,'_',code$route)
    code$count <- table(code$inn_route)[code$inn_route]
    code[code$count>1,3]<-NA
    code$inn_route <- NULL
    code$count <- NULL
    code <- unique(code)
    merge(event,code)
    
    
               inn   route id event   atc
    1 fusidic acid    oral  1 FALSE J01XC01
    2 fusidic acid topical  2  TRUE D06AX01
    3    ibuprofen unknown  1  TRUE    <NA>
    

    【讨论】:

    • 感谢您的回答。你的推理给了我一个更直接的方法的想法(见我的回答)。
    【解决方案2】:

    这是完成选项 2 的简单方法。从简单合并的结果开始:

    mrg <- merge(x = event,
                 y = code)
    
               inn   route id event     atc
    1 fusidic acid    oral  1 FALSE J01XC01
    2 fusidic acid topical  2  TRUE D06AX01
    3    ibuprofen unknown  1  TRUE R02AX02
    4    ibuprofen unknown  1  TRUE G02CC01
    5    ibuprofen unknown  1  TRUE M01AE01
    

    然后我们检查哪些行是重复的(删除atc 变量)。我们需要使用 duplicated 两次,因为它实际上会找到 duplicate 行,而不是有重复的行。因此,它会捕获第 4 行和第 5 行,但不会捕获第 3 行——要获得它,我们需要从相反的方向重复 duplicated。在这里阅读更多:Finding ALL duplicate rows, including “elements with smaller subscripts”:

    mrg$atc <- ifelse(duplicated(mrg[,-5]) | duplicated(mrg[,-5], fromLast = T),
                      NA,
                      mrg$atc)
    mrg
    
               inn   route id event     atc
    1 fusidic acid    oral  1 FALSE J01XC01
    2 fusidic acid topical  2  TRUE D06AX01
    3    ibuprofen unknown  1  TRUE    <NA>
    4    ibuprofen unknown  1  TRUE    <NA>
    5    ibuprofen unknown  1  TRUE    <NA>
    

    如果您想删除重复的第 4 行和第 5 行,只需再运行一次 duplicated 即可删除它们:

    mrg[!duplicated(mrg),]
    
               inn   route id event     atc
    1 fusidic acid    oral  1 FALSE J01XC01
    2 fusidic acid topical  2  TRUE D06AX01
    3    ibuprofen unknown  1  TRUE    <NA>
    

    【讨论】:

    • 感谢您的回答!此方法比ave 方法快得多。我在merge 之前在code[c("inn", "route")] 上应用了ifelse,以合并较小的数据帧以提高效率,我使用unique(x = code) 而不是code[!duplicated(x = code), ],因为根据文档它更有效。
    【解决方案3】:

    Grzegorz Sionkowski's answer 引导我找到以下解决方案:

    code$atc <- as.character(x = code$atc)
    
    code$atc <- ifelse(test = ave(x = code$atc,
                                  code$inn,
                                  code$route,
                                  FUN = length) > 1,
                       yes = NA,
                       no = code$atc)
    
    code <- unique(x = code)
    
    merge(x = event,
          y = code)
    
               inn   route id event     atc
    1 fusidic acid    oral  1 FALSE J01XC01
    2 fusidic acid topical  2  TRUE D06AX01
    3    ibuprofen unknown  1  TRUE    <NA>
    

    但是,由于ave 在我的真实数据上速度很慢,我想知道是否有更快的基础 R 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-02
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多