【问题标题】:How to replace all values in multiple columns that are not among the values in another column如何替换不在另一列中的值中的多列中的所有值
【发布时间】:2021-10-16 10:28:26
【问题描述】:

我有一个数据集,其中一个变量带有参与者 ID,多个变量带有同行提名(以 ID 的形式)。

我需要用 NA 替换同行提名变量中不在参与者 ID 中的所有数字。

例子:我有

ID       PN1       PN2
1         2         5
2         3         4
4         6         2      
5         2         7

我需要

ID       PN1       PN2
1         2         5
2         NA        4
4         NA        2      
5         2         NA

如果有人可以提供帮助,那就太好了!非常感谢您。

【问题讨论】:

  • 请使用dput() 准备可重现的示例数据。

标签: r replace na


【解决方案1】:

Base R 的替代方案,

df[,-1][matrix(!(unlist(df[,-1]) %in% df[,1]),nrow(df))] <- NA
df

给予,

  ID PN1 PN2
1  1   2   5
2  2  NA   4
3  4  NA   2
4  5   2  NA

【讨论】:

    【解决方案2】:
    library(tidyverse)
    
    df %>%
      mutate(across(-ID, ~if_else(. %in% ID, ., NA_real_)))
    

    给出:

    #   ID PN1 PN2
    # 1  1   2   5
    # 2  2  NA   4
    # 3  4  NA   2
    # 4  5   2  NA
    

    使用的数据:

    df <- data.frame(ID = c(1, 2, 4, 5),
                     PN1 = c(2, 3, 6, 2),
                     PN2 = c(5, 4, 2, 7))
    

    【讨论】:

      【解决方案3】:

      这是一个基本的 R 方式。
      除了 id 列之外的所有列上的 lapply 循环使用函数 is.na&lt;-NA 值分配给不在 df1[[1]] 中的向量元素。然后返回改变后的向量。

      df1[-1] <- lapply(df1[-1], function(x){
        is.na(x) <- !x %in% df1[[1]]
        x
      })
      
      df1
      #  ID PN1 PN2
      #1  1   2   5
      #2  2  NA   4
      #3  4  NA   2
      #4  5   2  NA
      

      dput 格式的数据

      df1 <-
      structure(list(ID = c(1L, 2L, 4L, 5L), 
      PN1 = c(2L, NA, NA, 2L), PN2 = c(5L, 4L, 2L, NA)), 
      row.names = c(NA, -4L), class = "data.frame")
      

      【讨论】:

        【解决方案4】:

        我们可以将mutatecase_when 一起使用:

        library(dplyr)
        df %>% 
          mutate(across(starts_with("PN"), ~case_when(!(. %in% ID) ~ NA_real_,
                                                      TRUE ~ as.numeric(.))))
            
        

        输出:

        # A tibble: 4 x 3
             ID   PN1   PN2
          <int> <dbl> <dbl>
        1     1     2     5
        2     2    NA     4
        3     4    NA     2
        4     5     2    NA
        

        【讨论】:

          【解决方案5】:

          使用 data.table,您可以 (l) 将函数 fifelse() 应用于每一列 你选择了.SD & .SDcols

          require(data.table)
          
          cols = grep('PN', names(df)) # column indices (or names)
          df[ , lapply(.SD, function(x) fifelse(!x %in% ID, NA_real_, x)),
              .SDcols = cols ]
          

          来自@deschen 的数据:

          df = data.frame(ID = c(1, 2, 4, 5),
                          PN1 = c(2, 3, 6, 2),
                          PN2 = c(5, 4, 2, 7))
          setDT(df)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-11
            • 1970-01-01
            • 2019-03-28
            • 1970-01-01
            • 2016-02-04
            相关资源
            最近更新 更多