caio.valente14
caio.valente14

Reputation: 87

Why can't I change the type of some columns when dataframes are inside a list?

I've been trying to run some part of code in rstudio that identifies the columns that are factors and then change them to character.
When I try to do out of the for loop, it works well, but to make the code look better and to get my work done in an easier way.
So, I put all data frames that I need to do change the type of the columns from factor to character inside a list and ran inside a for loop, but it didn't work this way.
Here are both code:

# This works well

i <- sapply(falha, is.factor)
falha[i] <- lapply(falha[i], as.character)

# This doesn't work

tab_list <- list(espacamento, falha, talhao, censo)
for (x in tab_list){ 
  i <- sapply(x, is.factor) 
  x[i] <- lapply(x[i], as.character) 
} 

Upvotes: 0

Views: 73

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173928

The problem is that you when you do for(x in tab_list), then in each iteration of the loop, x is a copy of each item in the list. It is not an alias for the item in the list. Here's a very simple example:

my_list <- list(1, 1)
my_list
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 1

for(x in my_list) {x <- 2}
my_list
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 1

If x was a reference to an item on the list, then the original list would be changed, but it isn't.

It's often helpful to break a problem like this down to simpler parts. In your case, you can write a function that works well with a single data frame:

factor_to_char <- function(x){
  are_factors <- sapply(x, is.factor)
  x[, are_factors] <- as.character(x[, are_factors])
  return(x)
}

Then you can easily apply it to all the data frames in your list with lapply:

lapply(tab_list, factor_to_char)

Or, if you really want to use a loop, you can do:

for(i in seq_along(tab_list)) {
  tab_list[[i]] <- factor_to_char(tab_list[[i]])
}

Upvotes: 1

Related Questions