3

I have the following two data frames that in a list called df.list

df1 <- data.frame(name=c("a","b","c"),total=c("1","2","3"),other=c("100","200","300"))
df2 <- data.frame(name=c("d","e","f"),total=c("4","5","6"),other=c("100","200","300"))



df.list <- list(df1,df2)

[[1]]
  name total other
1    a     1   100
2    b     2   200
3    c     3   300

[[2]]
  name total other
1    d     4   100
2    e     5   200
3    f     6   300

I want to be able to go through each data frame in the list and covert the total and other columns to be numeric, and assign it back to df.list

I tried the following but it does not seem to work

lapply(df.list, function(x) as.numeric(x[2:3]))

3 Answers 3

3

We may use type.convert directly on the list

df.list2 <- type.convert(df.list, as.is = TRUE) 

-checking the structure

 str(df.list2)
List of 2
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "a" "b" "c"
  ..$ total: int [1:3] 1 2 3
  ..$ other: int [1:3] 100 200 300
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "d" "e" "f"
  ..$ total: int [1:3] 4 5 6
  ..$ other: int [1:3] 100 200 300

If we want to loop, then as.integer/as.numeric works on vectors. So, we need to loop again

df.list2 <- lapply(df.list, function(x) {
             x[2:3] <- lapply(x[2:3], as.integer)
             x})
Sign up to request clarification or add additional context in comments.

Comments

3

Or maybe this one:

library(purrr)

df.list %>%
        map(., ~mutate(.x, across(c(other, total), ~as.numeric(.x)))) %>%
        str()

List of 2
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "a" "b" "c"
  ..$ total: num [1:3] 1 2 3
  ..$ other: num [1:3] 100 200 300
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "d" "e" "f"
  ..$ total: num [1:3] 4 5 6
  ..$ other: num [1:3] 100 200 300

3 Comments

I have Edited your answer to include all the variables to mutate as requested by the OP, without changing basic synthax. Still waiting for community approval
Oh I didn't notice that two variables have to transformed. Thank you, I will approve that myself. That . at the beginning of map is not needed here since we pass the whole data set unchanged into first argument.
Yeah, I sometimes put the dot anyway for clarity
2

you can create a function that works for each data frame such as the following functional_as_numeric() and then apply to each element in the list with map() from {purrr}. Personally I find {purrr}'s interface more consistent and easier to follow than the traditional _apply() functions.

library(purrr)

functional_as_numeric <- function(df) {
  df %>% mutate(
    total = as.numeric(total), 
    other = as.numeric(other)
  )
}

df.list.result <- df.list %>% 
  purrr::map(functional_as_numeric)

str(df.list.result)
List of 2
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "a" "b" "c"
  ..$ total: num [1:3] 1 2 3
  ..$ other: num [1:3] 100 200 300
 $ :'data.frame':   3 obs. of  3 variables:
  ..$ name : chr [1:3] "d" "e" "f"
  ..$ total: num [1:3] 4 5 6
  ..$ other: num [1:3] 100 200 300

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.