0

I am importing several hundred text files where I need to clean the column names.

t1 <- data.frame("A")
t2 <- data.frame(2)
names(t1) <- "COL one"
names(t2) <- "Col two"

I could do it coercing into a list and lapplying, but I subsequently need to join the dataframes and would prefer to not join on the list.

f <- list(t1=t1,t2=t2)
f2 <- lapply(f,janitor::clean_names)
  1. is there a method I can use to loop over dataframes, apply a function and return individual data.frames?
  2. Can I somehow coerce the f2 list back into dataframe t1 and t2?
Misha
  • 3,114
  • 8
  • 39
  • 60
  • It is easier to apply functions in a list and if you need separate dataframes in the end use `list2env(f2, .GlobalEnv)` ? – Ronak Shah Jan 30 '20 at 09:33
  • 1
    Why do you prefer not to use a list? Also, you could import directly into a list instead of manually converting lots of dataframes into a list. You could do something like `l <- lapply(list.files(), read.csv)`, then you could do whatever actions on the list. Then, you could easily join the dataframes using https://stackoverflow.com/questions/8091303/simultaneously-merge-multiple-data-frames-in-a-list or you could just bind them using https://stackoverflow.com/questions/15162197/combine-rbind-data-frames-and-create-column-with-name-of-original-data-frames. – David Arenburg Jan 30 '20 at 09:36
  • You could use the purrr library. Have a look at map() – Florian Jan 30 '20 at 09:37
  • Also, importing hundreds of files into your global environment is usually a very bad idea – David Arenburg Jan 30 '20 at 09:42
  • I know it can be done using list, but for the sake of curiosity/interest -- can it be done somehow? I dont see how list2env would work and map only returns a list, map_df would only return a single df - not multiple. – Misha Jan 30 '20 at 09:43
  • 1
    @Misha after applying all the functions in a list you have final list of dataframes in named list `f2`. If you do `list2env(f2, .GlobalEnv)` and check `t1` and `t2` (i.e names of the dataframe) they'll be updated/new ones. – Ronak Shah Jan 30 '20 at 09:54

2 Answers2

3

Only for the sake of curiosity :

dataframe_names <- c('t1', 't2')
#OR if you have more dataframes
#dataframe_names <- ls(pattern = '^t\\d+')

for (i in dataframe_names) {
   assign(i, janitor::clean_names(get(i)))
}

t1
#  col_one
#1       A

t2
#  col_two
#1       2
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2

You can use eval(parse(text=)) to do so, but it need your environment to only have these data.frames. You can then replace the 'NULL' with whatever you want to name you column

I think you can store these dataframes in a specific environnement and run it in a separate space, but I did not tried it yet.

t1 <- data.frame("A")
t2 <- data.frame(2)
names(t1) <- "COL one"
names(t2) <- "Col two"

l = ls() 
# note : you can also precise what you want in this vector of course, like so:
# l <- c('t1', 't2')

for(i in l){
  eval(parse(text = paste0('colnames(',i,')=NULL')))
}

t2
#   
# 1 2
Gowachin
  • 1,251
  • 2
  • 9
  • 17