0

Straight to the question. as1_list

I am trying to name data.frames in a list using name() and paste() but I am having trouble assigning them

num_fu = c('1','2','3','4','5','6','7','8','9')
as <- data.frame()

for (i in num_fu){
           assign(paste0("flnames", i), list.files(path = paste0("C:/Users/thepr/Documents/data/as", i), pattern = "\\.csv", full.names = TRUE))
           assign(paste0("as", i, "_list"), lapply(get(paste0("flnames", i)),
                                          function(x){base::as.data.frame(read.csv(x))}))
           
           nm <- gsub(".csv", "", basename(get(paste0("flnames", i)))) %>% str_sub(., 1,6)

nm returns

nm 1 "as1_01" "as1_02" "as1_03" "as1_04" "as1_05" "as1_07" "as1_08" "as1_09" "as1_11" "as1_13" [11] "as1_14" "as1_15" "as1_99"

and

names(as1_list) returns

> names(as1_list)
NULL

I tried get(paste0 ...

names(get(paste0("as", i, "_list"))) <- nm

this returns error: Error in names(get(paste0("as", i, "_list"))) <- nm : target of assignment expands to non-language object

so I tried

names(eval(parse(text = paste0("as", i, "_list")))) <- nm

and this occurred: Error in names(eval(parse(text = paste0("as", i, "_list")))) <- nm : target of assignment expands to non-language object

I have also tried assign() function using both of the above codes.

assign(names(get(paste0("as", i, "_list"))), nm)

Returns: Error in assign(names(get(paste0("as", i, "_list"))), nm) : invalid first argument

and

assign(names(eval(parse(text = paste0("as", i, "_list")))), nm)

Returns: Error in assign(names(eval(parse(text = paste0("as", i, "_list")))), nm) : invalid first argument

Please help. Thank you.

Progman
  • 16,827
  • 6
  • 33
  • 48
HJ WHY
  • 23
  • 8
  • and just typing ```as1_list <- nm``` works perfectly. but I want to do it using for loop or vectors since they are a cohort data with numerous follow-ups – HJ WHY May 21 '23 at 03:38
  • What should the result look like? A list, where each item is a `read.csv`-generated dataframe, named according to the CSV source file? Do you want to row-bind the list items to one big dataframe later on? – I_O May 21 '23 at 08:48
  • @I_O yes exactly, except column-bind. – HJ WHY May 22 '23 at 09:14

2 Answers2

1

I learned that it is mostly a bad idea to use assign() within for loops.

Just learn to use the vectorised nature of R to make it shine!

For example, consider storing the results of your for loop in a single list. You can still convert the list contents to single objects later on: Unlist a list of dataframes

I think, what you are trying to accomplish is to batch read .csv-files and renaming them. Have a look here: How to import multiple .csv files at once?

uke
  • 462
  • 1
  • 11
1

As specified in your comment, the following will give you a list of dataframes, each from a single CSV-file (starting with "as") and named with the filename excluding extension:

data_dir <- 'C:/Users/thepr/Documents/data/'
file_names <- list.files(data_dir, pattern = 'as.*\\.csv')

list_of_dataframes <- 
  file_names |>
  Map(f = \(fn) read.csv(file.path(data_dir,fn))) |>
  setNames(nm = gsub('\\.csv', '', file_names))

Note the use of Map to operate on a list (of file names, in this case) and avoid any for loop (generally a good idea in R).

I_O
  • 4,983
  • 2
  • 2
  • 15
  • Thank you very much for the input. ```data_dir <- 'C:/Users/thepr/Documents/data/as'``` is the exact data_dir, and also I have 9 lists of dataframes. The example I posted is just as1_list. and I have upto as9_list. So there should be vectors within 9 vectors? I should have mentioned this in the post. That's why I first used for loop. – HJ WHY May 23 '23 at 03:43
  • The above code does not work. ```list_of_dataframes, file_names``` returns 'named_list' and 'character(0)' – HJ WHY May 23 '23 at 04:07