【问题标题】:Replacing N/A in a data-frame with a value of choice用选择的值替换数据框中的 N/A
【发布时间】:2019-07-20 12:06:19
【问题描述】:

我一直在尝试用我选择的值替换数据框中的 N/A 条目,但没有成功。我检查了来源并尝试了下面的代码。谁能指出为什么我的命令不起作用,尽管一些消息来源建议它们应该起作用?

下面的数据框 exampleDF 在“zacko”列下包含一些 N/A 条目:

> exampleDF
             dates random letters action    zacko
1  2018-10-30 00:05:19     10       a     go   Mickey
2  2018-10-30 13:58:39      2       b    run   Donald
3  2018-10-31 03:51:59      1       c    fly     <NA>
4  2018-10-31 17:45:19     10       d    sit    Goofy
5  2018-11-01 07:38:39     10       e   jump    Daisy
6  2018-11-01 21:31:59     13       f   hike     <NA>
7  2018-11-02 11:25:19      6       g  dance     <NA>
8  2018-11-03 01:18:39      6       h     go Dagobert
9  2018-11-03 15:11:59      8       i  dance     <NA>
10 2018-11-04 05:05:19      6       j    run    Pluto
11 2018-11-04 18:58:39      2       k    sit     <NA>
12 2018-11-05 08:51:59      6       l  laugh   Minnie
13 2018-11-05 22:45:19      3       m    cry   Gustav
14 2018-11-06 12:38:39     11       n  write Reginald
15 2018-11-07 02:31:59      1       o    fly     <NA>

我查看了Correct syntax for mutate_if 并尝试根据我选择的值替换这些条目

exampleDF %>% mutate_if(is.character, funs(ifelse(is.na(.), 
"REPLACEMENT",.)))
        Warning message:
funs() is soft deprecated as of dplyr 0.8.0
please use list() instead
        # Before:
funs(name = f(.)
        # After: 
list(name = ~f(.))

> exampleDF %>% mutate_if(is.character, list(ifelse(is.na(.), 
"REPLACEMENT",.)))
Error: Can't create call to non-callable object
Call `rlang::last_error()` to see a backtrace

没有成功(您可以从错误消息中看到)。有趣的是,下面的命令在控制台上就像一个魅力:

> df <- tibble(x = c(1, 2, NA), y = c("a", NA, "b"), z = list(1:5, NULL, 
10:20))
> df
# A tibble: 3 x 3
      x y     z         
  <dbl> <chr> <list>    
1     1 a     <int [5]> 
2     2 NA    <NULL>    
3    NA b     <int [11]>
> df %>% replace_na(list(x = 0, y = "unknown"))
# A tibble: 3 x 3
      x y       z         
  <dbl> <chr>   <list>    
1     1 a       <int [5]> 
2     2 unknown <NULL>    
3     0 b       <int [11]>

> df %>% mutate(x = replace_na(x, 0))
# A tibble: 3 x 3
      x y     z         
  <dbl> <chr> <list>    
1     1 a     <int [5]> 
2     2 NA    <NULL>    
3     0 b     <int [11]>

为什么等效命令不适用于我的数据框?请参阅下面的错误消息:

exampleDF %>% replace_na(list(dates = as.POSIXct("2018-10-30 13:58:39"), 
random = 5, letters = "a", action = "crying", zacko = "FRUSTRATION"))
                 dates random letters action    zacko
1  2018-10-30 00:05:19     10       a     go   Mickey
2  2018-10-30 13:58:39      2       b    run   Donald
3  2018-10-31 03:51:59      1       c    fly     <NA>
4  2018-10-31 17:45:19     10       d    sit    Goofy
5  2018-11-01 07:38:39     10       e   jump    Daisy
6  2018-11-01 21:31:59     13       f   hike     <NA>
7  2018-11-02 11:25:19      6       g  dance     <NA>
8  2018-11-03 01:18:39      6       h     go Dagobert
9  2018-11-03 15:11:59      8       i  dance     <NA>
10 2018-11-04 05:05:19      6       j    run    Pluto
11 2018-11-04 18:58:39      2       k    sit     <NA>
12 2018-11-05 08:51:59      6       l  laugh   Minnie
13 2018-11-05 22:45:19      3       m    cry   Gustav
14 2018-11-06 12:38:39     11       n  write Reginald
15 2018-11-07 02:31:59      1       o    fly     <NA>
Warning messages:
1: In `[<-.factor`(`*tmp*`, !is_complete(data[[var]]), value = "crying") :
  invalid factor level, NA generated
2: In `[<-.factor`(`*tmp*`, !is_complete(data[[var]]), value = 
"FRUSTRATION") :
  invalid factor level, NA generated


> exampleDF %>% mutate(zacko = replace_na(zacko, "GAGA"))
                 dates random letters action    zacko
1  2018-10-30 00:05:19     10       a     go   Mickey
2  2018-10-30 13:58:39      2       b    run   Donald
3  2018-10-31 03:51:59      1       c    fly     <NA>
4  2018-10-31 17:45:19     10       d    sit    Goofy
5  2018-11-01 07:38:39     10       e   jump    Daisy
6  2018-11-01 21:31:59     13       f   hike     <NA>
7  2018-11-02 11:25:19      6       g  dance     <NA>
8  2018-11-03 01:18:39      6       h     go Dagobert
9  2018-11-03 15:11:59      8       i  dance     <NA>
10 2018-11-04 05:05:19      6       j    run    Pluto
11 2018-11-04 18:58:39      2       k    sit     <NA>
12 2018-11-05 08:51:59      6       l  laugh   Minnie
13 2018-11-05 22:45:19      3       m    cry   Gustav
14 2018-11-06 12:38:39     11       n  write Reginald
15 2018-11-07 02:31:59      1       o    fly     <NA>
Warning message:
In `[<-.factor`(`*tmp*`, !is_complete(data), value = "GAGA") :
  invalid factor level, NA generated

按照Correct syntax for mutate_if 中给出的示例和replace_na(data, replace, ...) 的帮助文件中给出的示例(需要tidyr 包),我本来希望我的上面的代码可以工作。

【问题讨论】:

    标签: r


    【解决方案1】:

    实际上,您的问题不是由于替换不工作,而是zacko 是一个因素。

    关于您的第一次尝试:尽管有警告,但尝试正常工作并将 NA 替换为“REPLACEMENT”(但请参阅下面有关因素的说明!)。新语法有点不同,要使用list 而不是funs,你必须像这样使用波浪号:

    exampleDF %>% mutate_if(is.character, list(~ ifelse(is.na(.), "REPLACEMENT", .)))
    

    如果zacko 是一个字符向量,另一个也可以工作......或者更确切地说,可以工作。显然(我不确定,因为您选择不使用dput 给我们您的示例数据)exampleDF$zacko 是一个因素。如果您尝试在某个因子中输入一个值,但该值不是级别之一,您会收到以下错误:

    > x <- factor(c("a", "b", "c"))
    > x[1] <- "REPLACEMENT"
    Warning message:
    In `[<-.factor`(`*tmp*`, 1, value = "REPLACEMENT") :
      invalid factor level, NA generated
    > x
    [1] <NA> b    c   
    Levels: a b c
    

    所以您确实替换了它,但由于它是一个因素,并且 REPLACEMENT 不是级别之一,它已被NA 替换再次。试试这个:

    exampleDF$zacko <- as.character(exampleDF$zacko)
    

    您的代码现在应该可以正常工作了。或者,如果您想保留它作为一个因素,请将“FRUSTRATION”添加到zacko 的级别:

    levels(exampleDF$zacko) <- c(levels(exampleDF$zacko), "FRUSTRATION")
    

    另请注意,默认情况下,data.frame 会将字符向量转换为因子:

    > foo <- data.frame(zacko=letters[1:5])
    > foo$zacko
    [1] a b c d e
    Levels: a b c d e
    

    这是一种非常烦人且危险的行为。你不想要那个!这就是为什么许多 R 用户在他们的个人资料中设置以下内容的原因:

    options(stringsAsFactors=FALSE)
    

    tibble 或数据表的行为并非如此:

    > foo <- tibble(zacko=letters[1:5])
    > foo$zacko
    [1] "a" "b" "c" "d" "e"
    

    最后,在这种简单的情况下,我可能会使用良好的旧基础 R:

    exampleDF$zacko[ is.na(exampleDF$zacko) ] <- "REPLACEMENT"
    

    【讨论】:

      【解决方案2】:

      我尽量避免因素并使用if_na() 来做到这一点。首先,我将 zacko 从因子转换为字符。

      代码

      library(hablar)
      
      df %>% 
        convert(chr(zacko)) %>% 
        mutate_if(is.character, ~if_na(., "REPLACEMENT"))
      

      结果

         random zacko      
          <int> <chr>      
       1     10 Mickey     
       2      2 Donald     
       3      1 REPLACEMENT
       4     10 Goofy      
       5     10 Daisy      
       6     13 REPLACEMENT
       7      6 REPLACEMENT
       8      6 Dagobert   
       9      8 REPLACEMENT
      10      6 Pluto      
      11      2 REPLACEMENT
      12      6 Minnie     
      13      3 Gustav     
      14     11 Reginald   
      15      1 REPLACEMENT
      

      数据

      df <- structure(list(random = c(10L, 2L, 1L, 10L, 10L, 13L, 6L, 6L, 
                                      8L, 6L, 2L, 6L, 3L, 11L, 1L), zacko = structure(c(6L, 3L, NA, 
                                                                                        4L, 2L, NA, NA, 1L, NA, 8L, NA, 7L, 5L, 9L, NA), .Label = c("Dagobert", 
                                                                                                                                                    "Daisy", "Donald", "Goofy", "Gustav", "Mickey", "Minnie", "Pluto", 
                                                                                                                                                    "Reginald"), class = "factor")), class = c("tbl_df", "tbl", "data.frame"
                                                                                                                                                    ), row.names = c(NA, -15L))
      

      【讨论】:

        猜你喜欢
        • 2022-01-08
        • 1970-01-01
        • 1970-01-01
        • 2019-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        • 2020-04-22
        相关资源
        最近更新 更多