【问题标题】:R: Delete certain values from all columnsR:从所有列中删除某些值
【发布时间】:2015-03-09 12:21:24
【问题描述】:

我有一个如下所示的数据框:

  compare   col1    col2   col3   (...)
1   cat01 bird02  bird03  cat01   (...)
2  bird02 bird03   cat02  dog01   (...)
3   cat02 bird04 horse01  cat06   (...)
4   cat03  cat01  bird04  cat08   (...)
5   dog01 bird02   dog01 bird03   (...)

我想将 col1、col2、col3 等中未出现在“比较”列中的所有值更改为 NA。

  compare   col1  col2  col3
1   cat01 bird02  <NA> cat01
2  bird02   <NA> cat02 dog01
3   cat02   <NA>  <NA>  <NA>
4   cat03  cat01  <NA>  <NA>
5   dog01 bird02 dog01  <NA>

对于类似的情况,我使用了

data$col1[!data$col1 %in% data$compare] <- NA

之前,但我必须手动更改所有列。由于这个特定的数据框有大量的列,有什么方法可以通过一次比较所有其他列及其值来更快、更轻松地完成此操作?

谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一个可能的 data.table 解决方案,用于通过引用更新您的数据集(您可以使用 setfor 循环来提高性能,但如果您的数据集不是太大,您可能不需要它)

    library(data.table)
    indx <- unique(df$compare)
    setDT(df)[, names(df)[-1] := lapply(.SD, function(x) replace(x, !x %in% indx, NA)), .SDcols = -"compare"][]
    #    compare   col1  col2  col3
    # 1:   cat01 bird02    NA cat01
    # 2:  bird02     NA cat02 dog01
    # 3:   cat02     NA    NA    NA
    # 4:   cat03  cat01    NA    NA
    # 5:   dog01 bird02 dog01    NA
    

    【讨论】:

      【解决方案2】:

      使用dplyr

      library(dplyr)
      df %>% mutate_each(funs(ifelse(. %in% df[,1], ., NA)), -compare)
      

      你得到:

      #  compare   col1  col2  col3
      #1   cat01 bird02  <NA> cat01
      #2  bird02   <NA> cat02 dog01
      #3   cat02   <NA>  <NA>  <NA>
      #4   cat03  cat01  <NA>  <NA>
      #5   dog01 bird02 dog01  <NA>
      

      【讨论】:

        【解决方案3】:

        你可以试试

        df1[-1][!mapply(`%in%`, df1[-1], df1[1])] <- NA
        df1
        #  compare   col1  col2  col3
        #1   cat01 bird02  <NA> cat01
        #2  bird02   <NA> cat02 dog01
        #3   cat02   <NA>  <NA>  <NA>
        #4   cat03  cat01  <NA>  <NA>
        #5   dog01 bird02 dog01  <NA>
        

        或者

        df1[-1][`dim<-`(!grepl(paste(df1[,1], collapse="|"),
                    as.matrix(df1[-1])), dim(df1[-1]))] <- NA
        

        【讨论】:

        • 这会稍微紧凑一点:df1[ !mapply('%in%', df1, df1[1])] &lt;- NA
        【解决方案4】:

        如果我在 R 控制台附近,我会尝试

         df[ ! df %in% df[[1]] ] <- NA 
        

        使用矩阵应该可以成功,但我现在无法对其进行测试。您不需要排除 col 1 b/c 它们都在 col1 中。

        编辑:嗯,那没用,....但是如果它是一个字符矩阵....

         dat <- as.matrix(df)
        
         dat[ ! dat %in% dat[,1] ] <- NA
         dat
        #-----------
          compare  col1     col2    col3   
        1 "cat01"  "bird02" NA      "cat01"
        2 "bird02" NA       "cat02" "dog01"
        3 "cat02"  NA       NA      NA     
        4 "cat03"  "cat01"  NA      NA     
        5 "dog01"  "bird02" "dog01" NA   
        

        【讨论】:

          【解决方案5】:

          你可以使用is.na&lt;-函数:

          is.na(data[-1]) <- matrix(!as.matrix(data[-1]) %in% data$compare, nrow(data))
          
          #   compare   col1  col2  col3
          # 1   cat01 bird02  <NA> cat01
          # 2  bird02   <NA> cat02 dog01
          # 3   cat02   <NA>  <NA>  <NA>
          # 4   cat03  cat01  <NA>  <NA>
          # 5   dog01 bird02 dog01  <NA>
          

          【讨论】:

            【解决方案6】:

            我的方法是:

            df[,2:ncol(df)][apply(df[,2:ncol(df)], 2, function(x) x %in% df[,1])==F] <- NA
            
            #  compare   col1  col2  col3
            #1   cat01 bird02  <NA> cat01
            #2  bird02   <NA> cat02 dog01
            #3   cat02   <NA>  <NA>  <NA>
            #4   cat03  cat01  <NA>  <NA>
            #5   dog01 bird02 dog01  <NA>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-11
              • 2018-02-01
              • 2019-01-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多