【问题标题】:Replace all particular values in a data frame替换数据框中的所有特定值
【发布时间】:2022-01-24 04:22:33
【问题描述】:

拥有一个数据框,我该如何替换所有行和列中的所有特定值。例如,我想用NA's 替换所有空记录(不输入位置):

df <- data.frame(list(A=c("", "xyz", "jkl"), B=c(12, "", 100)))

    A   B
1      12
2  xyz    
3  jkl 100

预期结果:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

【问题讨论】:

    标签: r dataframe replace


    【解决方案1】:

    这里有几个dplyr 选项:

    library(dplyr)
    
    # all columns:
    df %>% 
      mutate_all(~na_if(., ''))
    
    # specific column types:
    df %>% 
      mutate_if(is.factor, ~na_if(., ''))
    
    # specific columns:  
    df %>% 
      mutate_at(vars(A, B), ~na_if(., ''))
    
    # or:
    df %>% 
      mutate(A = replace(A, A == '', NA))
    
    # replace can be used if you want something other than NA:
    df %>% 
      mutate(A = as.character(A)) %>% 
      mutate(A = replace(A, A == '', 'used to be empty'))
    

    【讨论】:

    • 您将如何使用全列解决方案将整个数据集中的多个字符串替换为 NA?
    • 这些选项仍然完全有效,只需注意“mutate_at”和“mutate_all”函数已被“across()”取代。它们仍然受支持,但 R 建议改为“across()”。更多细节在这里:dplyr.tidyverse.org/reference/across.html
    【解决方案2】:

    如果您想替换数据框中的多个值,循环遍历所有列可能会有所帮助。

    说要替换""100

    na_codes <- c(100, "")
    for (i in seq_along(df)) {
        df[[i]][df[[i]] %in% na_codes] <- NA
    }
    

    【讨论】:

      【解决方案3】:

      我们可以使用 data.table 快速获取。 首先创建没有因子的df,

      df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)), stringsAsFactors=F)
      

      现在你可以使用

      setDT(df)
      for (jj in 1:ncol(df)) set(df, i = which(df[[jj]]==""), j = jj, v = NA)
      

      您可以将其转换回 data.frame

      setDF(df)
      

      如果您只想使用 data.frame 并保留因子比较困难,则需要使用

      levels(df$value)[levels(df$value)==""] <- NA
      

      其中 value 是每列的名称。您需要将其插入循环中。

      【讨论】:

      • 为什么要为这个用例使用外部库?如果可以用一行来解决,为什么要循环?除了已经存在的答案之外,您的答案如何增加价值?我不打算苛刻,我想我错过了一些东西,因此提出了问题。
      • 处理大型数据集要快得多。它添加了一个替代方案,以便用户可以为他选择最好的。
      【解决方案4】:

      由于 PikkuKatja 和 glallen 要求提供更通用的解决方案,我还不能发表评论,所以我会写一个答案。您可以组合语句,如下所示:

      > df[df=="" | df==12] <- NA
      > df
           A    B
      1  <NA> <NA>
      2  xyz  <NA>
      3  jkl  100
      

      对于因子,zxzak 的代码已经产生了因子:

      > df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)))
      > str(df)
      'data.frame':   3 obs. of  2 variables:
       $ A: Factor w/ 3 levels "","jkl","xyz": 1 3 2
       $ B: Factor w/ 3 levels "","100","12": 3 1 2
      

      如果遇到麻烦,我建议暂时放弃这些因素。

      df[] <- lapply(df, as.character)
      

      【讨论】:

        【解决方案5】:

        像这样:

        > df[df==""]<-NA
        > df
             A    B
        1 <NA>   12
        2  xyz <NA>
        3  jkl  100
        

        【讨论】:

        • 有没有办法为超过 1 个值有效地做到这一点!?
        • 这不适用于因子,df[df=="xyz"]&lt;-"abc" 将出现“无效因子水平”错误。有没有更通用的解决方案?
        • 不适合我。我试过这个:dfSmallDiscreteCustomSalary[dfSmallDiscreteCustomSalary$salary=="50K
        • glallen ...如果您尝试使用已经是一个因子的新值修改因子列,那么我将建议的可能有更聪明的方法,但您可以 df $factorcolumn
        • 找到了:df.na.replace(df.columns, Map("" -> "NA")).show。有趣的是,我无法用 null 作为值替换。我得到:java.lang.IllegalArgumentException:不支持的值类型 java.lang.String (null)。在 org.apache.spark.sql.DataFrameNaFunctions.org$apache$spark$sql$DataFrameNaFunctions$$convertToDouble(DataFrameNaFunctions.scala:434)
        猜你喜欢
        • 2019-12-05
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        • 2020-10-23
        • 2022-07-14
        相关资源
        最近更新 更多