【问题标题】:How to replace all kinds of NA (true NA and character strings) in R如何在R中替换各种NA(真正的NA和字符串)
【发布时间】:2021-12-27 09:59:44
【问题描述】:

我有一个大数据框,integercharacter 中有NA。 我想补充各种NA-。 有一个简单的例子如下。 df 是这样的:

library(tibble)
df = tibble(a = c(1,2, NA),
                b = c('a','b', 'NA'),
                c = c('1.5(1,7, 1.9)', '1.3 (1.4, 1.5)', 'NA (NA, NA)'))

> df
# A tibble: 3 x 3
      a b     c             
  <dbl> <chr> <chr>         
1     1 a     1.5(1,7, 1.9) 
2     2 b     1.3 (1.4, 1.5)
3    NA NA    NA (NA, NA)  

我期望df 应该是这样的:

df_expected = tibble(a = c(1,2, '-'),
                     b = c('a','b', '-'),
                     c = c('1.5(1,7, 1.9)', '1.3 (1.4, 1.5)', '-'))
> df_expected
# A tibble: 3 x 3
  a     b     c             
  <chr> <chr> <chr>         
1 1     a     1.5(1,7, 1.9) 
2 2     b     1.3 (1.4, 1.5)
3 -     -     -            

任何帮助将不胜感激!

【问题讨论】:

  • "各种NA" - 你有多少种?最好使用具有固定匹配的 gsub。

标签: r dplyr tidyverse


【解决方案1】:

你可以这样做:

library(tidyverse)    
df %>%
  mutate(across(everything(), as.character),
         across(everything(), ~if_else(is.na(.) | str_detect(., "NA"), "-", .)))

# A tibble: 3 x 3
  a     b     c             
  <chr> <chr> <chr>         
1 1     a     1.5(1,7, 1.9) 
2 2     b     1.3 (1.4, 1.5)
3 -     -     -             

【讨论】:

  • 请注意:“BANANA”也会变成“-”。
  • 是的。所以我可能应该确保 NA 部分之前或之后没有我要说的字母。
【解决方案2】:

另一种选择是在自定义函数中使用ifelsegrepl,然后调用mutate_all

na_replace <- function(x) {
  
  ifelse(is.na(x) | grepl('NA', x), '-', x)
  
}

df %>% 
  mutate_all(na_replace)

由于mutate_all 已被取代并且可能不会收到进一步的更新,您可以将mutateacross 一起使用:

df %>% 
  mutate(across(everything(), na_replace))

两个选项都给出:

## A tibble: 3 × 3
#  a     b     c             
#  <chr> <chr> <chr>         
#1 1     a     1.5(1,7, 1.9) 
#2 2     b     1.3 (1.4, 1.5)
#3 -     -     -             

编辑

如果我们有BANANA,我们可以在grepl 中使用'\\b' 转接:

na_replace <- function(x) {
  
  ifelse(is.na(x) | grepl('\\bNA', x, perl = TRUE), '-', x)
}

df %>% 
  mutate(across(everything(), na_replace))
## A tibble: 3 × 3
#  a     b      c             
#  <chr> <chr>  <chr>         
#1 1     a      1.5(1,7, 1.9) 
#2 2     b      1.3 (1.4, 1.5)
#3 -     BANANA -             

【讨论】:

  • 你不应该再使用mutate_all,因为它已被acrossmutate一起使用所取代。
  • mutate_allsuperseded 这意味着它不会消失。
  • 是的,但它不会从任何新功能中受益,所以我想它比开发人员建议的新版本更可取。
猜你喜欢
  • 1970-01-01
  • 2018-12-29
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多