Home > other >  Convert na_character_ to "NA"
Convert na_character_ to "NA"

Time:12-20

I would like to convert NA_charcater_ to "NA".

Data:

iris_test <- head(iris)
iris_test[c(1,4),c(2,3)] <- NA_real_
iris_test[c(1,2),5] <- NA_character_
iris_test$Species <- as.character(iris_test$Species)
iris_test$NAs <- NA_character_
iris_test

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species  NAs
1          5.1          NA           NA         0.2    <NA> <NA>
2          4.9         3.0          1.4         0.2    <NA> <NA>
3          4.7         3.2          1.3         0.2  setosa <NA>
4          4.6          NA           NA         0.2  setosa <NA>
5          5.0         3.6          1.4         0.2  setosa <NA>
6          5.4         3.9          1.7         0.4  setosa <NA>

Expected_output:

expected <- iris_test
expected[c(1,2),5] <- "NA"
expected$NAs <- "NA"
expected

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species NAs
1          5.1          NA           NA         0.2      NA  NA
2          4.9         3.0          1.4         0.2      NA  NA
3          4.7         3.2          1.3         0.2  setosa  NA
4          4.6          NA           NA         0.2  setosa  NA
5          5.0         3.6          1.4         0.2  setosa  NA
6          5.4         3.9          1.7         0.4  setosa  NA

I tried the following but it failed miserably:

iris_test[(sapply(iris_test, class)=="character")&is.na(iris_test)] <- "NA"

CodePudding user response:

It is not recommended to convert to "NA". The issue in the code is that class returns a vector of length different than the matrix output of is.na. An option is to subset the columns based on the class and then apply the is.na on the subset and do the assign

i1 <- sapply(iris_test, is.character)
iris_test[i1][is.na(iris_test[i1])] <- "NA"

-output

> str(iris_test)
'data.frame':   6 obs. of  6 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4
 $ Sepal.Width : num  NA 3 3.2 NA 3.6 3.9
 $ Petal.Length: num  NA 1.4 1.3 NA 1.4 1.7
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4
 $ Species     : chr  "NA" "NA" "setosa" "setosa" ...
 $ NAs         : chr  "NA" "NA" "NA" "NA" ...

CodePudding user response:

We could use replace_na wrapped along with as.character():

library(dplyr)
library(tidyr)

iris_test %>% 
  mutate(across(everything(), ~replace_na(as.character(.), "NA")))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species NAs
1          5.1          NA           NA         0.2      NA  NA
2          4.9           3          1.4         0.2      NA  NA
3          4.7         3.2          1.3         0.2  setosa  NA
4          4.6          NA           NA         0.2  setosa  NA
5            5         3.6          1.4         0.2  setosa  NA
6          5.4         3.9          1.7         0.4  setosa  NA

CodePudding user response:

I end up with the following solution:

iris_test%>%mutate_if(is_character,replace_na,"NA")
  •  Tags:  
  • r
  • Related