Reputation: 555
I have a list of data frames as follows:
dat_1 <- data.frame(x = c("A", "B", "C", "D") %>% as.factor)
dat_2 <- data.frame(x = c("A", "B", "C", "D") %>% as.character)
dat <- list("dat_1" = dat_1, "dat_2" = dat_2)
Some columns are factors and other are characters. I need to replace any instance of "C" with NA for all data frames in the list. How would I accomplish this?
I know I can accomplish this using the following code, but I want to avoid hardcoding each data frame in the list if possible:
dat[["dat_2"]][dat[["dat_2"]] == "C"] <- NA
Upvotes: 2
Views: 189
Reputation: 887901
We can use na_if
library(dplyr)
library(purrr)
map(dat, ~ .x %>%
mutate_all(na_if, "C"))
#$dat_1
# x
#1 A
#2 B
#3 <NA>
#4 D
#$dat_2
# x
#1 A
#2 B
#3 <NA>
#4 D
Upvotes: 2
Reputation: 389275
We can use dplyr::recode
library(dplyr)
purrr::map(dat, . %>% mutate_all(~recode(., "C"=NA_character_)))
#$dat_1
# x
#1 A
#2 B
#3 <NA>
#4 D
#$dat_2
# x
#1 A
#2 B
#3 <NA>
#4 D
Upvotes: 2
Reputation: 39174
First of all, the way you created the data frame will cause the columns of the data frames to be all factor. I modified your code as follows to make the first data frame to be factor and the second data frame to be character.
dat_1 <- data.frame(x = c("A", "B", "C", "D"))
dat_2 <- data.frame(x = c("A", "B", "C", "D"), stringsAsFactors = FALSE)
dat <- list("dat_1" = dat_1, "dat_2" = dat_2)
We can use the following code to replace all "C" to be NA
.
dat2 <- lapply(dat, function(x){
x[] <- lapply(x, function(x) replace(x, x %in% "C", NA))
return(x)
})
dat2
# $dat_1
# x
# 1 A
# 2 B
# 3 <NA>
# 4 D
#
# $dat_2
# x
# 1 A
# 2 B
# 3 <NA>
# 4 D
The code will not change the column types.
lapply(dat2, function(x) sapply(x, class))
# $dat_1
# x
# "factor"
#
# $dat_2
# x
# "character"
Upvotes: 3
Reputation: 978
lapply(dat, function (x) {sapply(x, function (y) {y <- as.character(y); y[which(y == "C")] <- NA; return (y)})})
Upvotes: 2