1

I have a loop to read in a series of .csv files

for (i in 1:3)
{
  nam <- paste0("A_tree", i)
  assign(nam, read.csv(sprintf("/Users/sethparker/Documents/%d_tree_from_data.txt", i), header = FALSE))
}

This works fine and generates a series of files comparable to this example data

A_tree1 <- data.frame(cbind(c(1:5),c(1:5),c(1:5)))
A_tree2 <- data.frame(cbind(c(2:6),c(2:6),c(2:6)))
A_tree3 <- data.frame(cbind(c(3:10),c(3:10),c(3:10)))

What I want to do is add column names, and populate 2 new columns with data (month and model run). My current successful approach is to do this individually, like this:

colnames(A_tree1) <-  c("GPP","NPP","LA")
A_tree1$month <- seq.int(nrow(A_tree1))
A_tree1$run <- c("1")
colnames(A_tree2) <-  c("GPP","NPP","LA")
A_tree2$month <- seq.int(nrow(A_tree2))
A_tree2$run <- c("2")
colnames(A_tree3) <-  c("GPP","NPP","LA")
A_tree3$month <- seq.int(nrow(A_tree3))
A_tree3$run <- c("3")

This is extremely inefficient for the number of _tree objects I have. Attempts to modify the loop with paste0() or sprintf() to incorporate these desired manipulations have resulted in Error: target of assignment expands to non-language object. I think I understand why this error is appearing based on reading other posts (Error in <my code> : target of assignment expands to non-language object). Is it possible to do what I want within my for loop? If not, how could I automate this better?

sethparker
  • 85
  • 6

1 Answers1

3

You can use lapply:

n <- index #(include here the total index)
l <- lapply(1:n, function(i) {
  # this is the same of sprintf, but i prefer paste0
  # importing data on each index i
  r <- read.csv(
    paste0("/Users/sethparker/Documents/", i, "_tree_from_data.txt"), 
    header = FALSE
  )
  
  # creating add columns
  r$month <- seq.int(nrow(r))
  r$run <- i
  
  return(r)
})

# lapply will return a list for you, if you desire to append tables
# include a %>% operator and a bind_rows() call (dplyr package)
l %>%
  bind_rows() # like this

blmayer
  • 300
  • 4
  • 15