【问题标题】:Fill the null values in R dataframe with default but distinct values用默认但不同的值填充 R 数据框中的空值
【发布时间】:2017-11-05 22:02:01
【问题描述】:

我有一个 R 数据框,其中一列没有值。我想用不同的值填充这些值。

id  var1   var2   var3
A   25      26     abc
B   28      35     abk
C   55      46      
D   64      az     lft
J   cd      yz      
M   dg      ck     ja
......................
.........

我想用默认但不同的值填充这些空值。

预期输出:

   id  var1   var2   var3
A   25      26     abc
B   28      35     abk
C   55      46     NA1 
D   64      az     lft
J   cd      yz     NA2
M   dg      ck     ja
so now the other null value will be filled with NA3

使用 R 和 pandas 的解决方案比较好。

【问题讨论】:

    标签: python r pandas dataframe na


    【解决方案1】:

    R

    df$var3 = as.character(df$var3)
    df$var3 = replace(df$var3, df$var3 == "", paste0(NA, sequence(sum(df$var3 == ""))))
    df
    #  d var1 var2 var3
    #1 A   25   26  abc
    #2 B   28   35  abk
    #3 C   55   46  NA1
    #4 D   64   az  lft
    #5 J   cd   yz  NA2
    #6 M   dg   ck   ja
    

    数据

    df = structure(list(d = c("A", "B", "C", "D", "J", "M"), var1 = c("25", 
    "28", "55", "64", "cd", "dg"), var2 = c("26", "35", "46", "az", 
    "yz", "ck"), var3 = structure(c(2L, 3L, 1L, 5L, 1L, 4L), .Label = c("", 
    "abc", "abk", "ja", "lft"), class = "factor")), .Names = c("d", 
    "var1", "var2", "var3"), row.names = c(NA, -6L), class = "data.frame")
    

    【讨论】:

    • 它确实添加了“NA”,但没有在NA之后添加序列号。
    • Warning message: In [(*tmp*, list, value = c("NA1", "NA2", "NA3", "NA4", : invalid factor level, NA generated
    • 另外,使用make.unique,类似make.unique(rep("val", sum(df$var3 == ""))) 的东西应该这样做,df$var3 == "" 可以写成!nzchar(df$var3)。不确定速度影响。
    【解决方案2】:

    使用data.table,这是由

    完成的
    library(data.table)
    setDT(DF)[var3 == "", var3 := rowid(var3, prefix = "NA")][]
    
       id var1 var2 var3
    1:  A   25   26  abc
    2:  B   28   35  abk
    3:  C   55   46  NA1
    4:  D   64   az  lft
    5:  J   cd   yz  NA2
    6:  M   dg   ck   ja
    

    请注意,这适用于无需转换的字符或因子列。赋值运算符:= 仅替换DF$var3 的更新元素就地,即,不复制整个数据对象以节省时间和内存。

    这可以通过在更新语句前后执行address(DF$var3)来验证。 base R solution 复制整个 data.frame df 两次(检查 address(df))。

    数据

    DF <- read.table(fill = TRUE, header = TRUE, 
    text = "id  var1   var2   var3
    A   25      26     abc
    B   28      35     abk
    C   55      46      
    D   64      az     lft
    J   cd      yz      
    M   dg      ck     ja")
    
    str(DF)
    
    'data.frame': 6 obs. of  4 variables:
     $ id  : Factor w/ 6 levels "A","B","C","D",..: 1 2 3 4 5 6
     $ var1: Factor w/ 6 levels "25","28","55",..: 1 2 3 4 5 6
     $ var2: Factor w/ 6 levels "26","35","46",..: 1 2 3 4 6 5
     $ var3: Factor w/ 5 levels "","abc","abk",..: 2 3 1 5 1 4
    

    【讨论】:

      【解决方案3】:

      您也可以使用make.unique 填写唯一值。例如,

      dat$var3 <- as.character(dat$var3)
      dat$var3[!nzchar(dat$var3)] <- make.unique(rep("val", sum(!nzchar(dat$var3))))
      

      返回

      dat
        d var1 var2  var3
      1 A   25   26   abc
      2 B   28   35   abk
      3 C   55   46   val
      4 D   64   az   lft
      5 J   cd   yz val.1
      6 M   dg   ck    ja
      

      您可以使用 sep 参数调整默认分隔符,也可以将任何存根用作基础。我在这里使用了“val”。 nzchar 是另一种检查非空字符串的方法,例如 != ""。我最初使用! 来反转输出并指示空字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-10
        • 2016-09-07
        • 1970-01-01
        • 2020-11-29
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        相关资源
        最近更新 更多