Loop not working and not raising any error in R

Viewed 62

I am working with a list of df's, I would like to change this typo "-" for NA for every df row for every df column for every df in the list.

However when I run the next code and then unlist to verify if it worked, the output remains the same "-" insted of NA:

for(i in 1:length(df_list)){
      for(j in i){
        for(z in j){
          if(df_list[[i]][[j]][[z]] == "-"){
            return(NA)
          } else {
            df_list[[i]][[j]][[z]] 
          }
        }
      }
}

## unlist to verify ##
for(i in names(df_list)){
    assign(i, df_list[[i]], .GlobalEnv)
}

##verifying ##
df1[1, "col"]

// output //

"-"

Is there anyway to do this in R with other object?

3 Answers

There is no need for so many nested for loops, a simple lapply loop will change all "-" in all data frames to NA.

df_list <- lapply(df_list, function(x){
  is.na(x) <- x == "-"
  x
})

Test data creation code

f <- function(i){
  d <- data.frame(x = letters[1:5], y = 6:10, a = letters[1:5])
  d$x[sample(5, 1)] <- "-"
  d$a[sample(5, 2)] <- "-"
  d
}
df_list <- lapply(1:3, f)
rm(f)

An option with tidyverse would be

 library(dplyr)
 library(purrr)
 map(df_list, ~ .x %>%
                  mutate(across(everything(), na_if, "-")))

Does this work for your purpose?

lapply(df_list,function(v) replace(v,v=="-",NA))

Regarding the nest for loop in your code, you should not use return(NA), since it doesn't assign new values to the existing data.frames, which is the reason that the output remains the same "-" insted of NA.

You can try the version like below

for(i in 1:length(df_list)){
      for(j in i){
        for(z in j){
          if(df_list[[i]][[j]][[z]] == "-"){
            df_list[[i]][[j]][[z]] <- NA
          }
        }
      }
}
Related