【问题标题】:Can case_when report the names of the variables it selects as well as their values?case_when 可以报告它选择的变量的名称及其值吗?
【发布时间】:2020-10-18 07:07:48
【问题描述】:

我有一个数据集,其中对于每个唯一 DOI,特定变量的值分散在三个变量(列)的任意组合中。这是因为我在三个不同的在线搜索引擎中搜索了 DOI 信息并将结果合并到一个文件中。一个示例数据集如下:

df1 <- data.frame(
  'DOI' = c("A","B","C","D","E", "G", "H", "I")
  , 'V2' = c(1,NA,NA,4,5,NA,7, NA)
  , 'V3' = c(NA,2,NA,4,5,6,NA, NA)
  , 'V4' = c(NA,NA,3,4,NA,6,7, NA)
)

df1

  DOI V2 V3 V4
1   A  1 NA NA
2   B NA  2 NA
3   C NA NA  3
4   D  4  4  4
5   E  5  5 NA
6   G NA  6  6
7   H  7 NA  7
8   I NA NA NA

以下代码允许我选择数据,而不管它包含在三列(V2、V3 或 V4)中的哪一列,并将其保存在单个新变量 V5 中。

library(dplyr)
df2 <- df1 %>% mutate(V5 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ V2,
                            (is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
                            (is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V4,
                            (!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V2,
                            (!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ V3,
                            (is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ V3,
                            (!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ V2,
                            (is.na(V2) & is.na(V3) & is.na(V4) ) ~ V2,
                            TRUE ~ NA_real_))
df2

  DOI V2 V3 V4 V5
1   A  1 NA NA  1
2   B NA  2 NA  2
3   C NA NA  3  3
4   D  4  4  4  4
5   E  5  5 NA  5
6   G NA  6  6  6
7   H  7 NA  7  7
8   I NA NA NA NA

我还想记录(作为 V6),哪些变量(V2、V3 或 V4)是复制到 V5 中的数据的源。我尝试了以下方法,但它似乎只是复制了进入 V5 的变量的值,而不是变量本身的名称。

df3 <- df2 %>% mutate(V6 = case_when((!is.na(V2) & is.na(V3) & is.na(V4)) ~ "V2",
                                     (is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
                                     (is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V4",
                                     (!is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V2",
                                     (!is.na(V2) & !is.na(V3) & is.na(V4) ) ~ "V3",
                                     (is.na(V2) & !is.na(V3) & !is.na(V4) ) ~ "V3",
                                     (!is.na(V2) & is.na(V3) & !is.na(V4) ) ~ "V2",
                                     (is.na(V2) & is.na(V3) & is.na(V4) ) ~ "V2",
                                     TRUE ~ NA_real_))
df3

  DOI V2 V3 V4 V5 V6
1   A  1 NA NA  1  1
2   B NA  2 NA  2  2
3   C NA NA  3  3  3
4   D  4  4  4  4  4
5   E  5  5 NA  5  5
6   G NA  6  6  6  6
7   H  7 NA  7  7  7
8   I NA NA NA NA NA

是否也可以记录从中选择数据的变量的名称?这将允许跟踪我使用哪些搜索引擎来定位匹配的 DOI 信息。

【问题讨论】:

    标签: r dataframe dplyr case-when


    【解决方案1】:

    这是一个基本 R 选项,使用max.col 选择每行中的第一个非 NA 值和相应的列名。

    inds <- max.col(!is.na(df1[-1]), 'first')
    df1$V5 <- df1[-1][cbind(1:nrow(df1), inds)]
    df1$V6 <- names(df1[-1])[inds]
    #To replace column name with all NA value to NA
    df1$V6[rowSums(!is.na(df1[-1])) == 0] <- NA
    

    如果您对dplyr 解决方案感兴趣,您可以使用rowwisec_across

    library(dplyr)
    
    df1 %>%
      rowwise() %>%
      mutate(V5 = na.omit(c_across(V2:V4))[1], 
             V6 = names(.)[-1][which(!is.na(c_across(V2:V4)))[1]])
    
    #   DOI      V2    V3    V4    V5 V6   
    #  <chr> <dbl> <dbl> <dbl> <dbl> <chr>
    #1 A         1    NA    NA     1 V2   
    #2 B        NA     2    NA     2 V3   
    #3 C        NA    NA     3     3 V4   
    #4 D         4     4     4     4 V2   
    #5 E         5     5    NA     5 V2   
    #6 G        NA     6     6     6 V3   
    #7 H         7    NA     7     7 V2   
    #8 I        NA    NA    NA    NA NA   
    

    我们使用-1 是因为我们想从计算中忽略第一列DOI

    【讨论】:

      【解决方案2】:

      使用基础 R:

      > df1
        DOI V2 V3 V4
      1   A  1 NA NA
      2   B NA  2 NA
      3   C NA NA  3
      4   D  4  4  4
      5   E  5  5 NA
      6   G NA  6  6
      7   H  7 NA  7
      8   I NA NA NA
      > df1$V5 <- apply(df1[2:4], 1, max, na.rm = T)
      > df1$V5[is.infinite(df1$V5)] <- NA
      > df1$V6 <- apply(df1[2:4],1,which.max)
      > df1$V6 <- as.integer(df1$V6)
      > df1$V6 <- names(df1)[2:4][df1$V6]
      > df1
        DOI V2 V3 V4 V5   V6
      1   A  1 NA NA  1   V2
      2   B NA  2 NA  2   V3
      3   C NA NA  3  3   V4
      4   D  4  4  4  4   V2
      5   E  5  5 NA  5   V2
      6   G NA  6  6  6   V3
      7   H  7 NA  7  7   V2
      8   I NA NA NA NA <NA>
      > 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-17
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多