3

I have a variable named SAL_mean created like this (I want to make a loop once I figure this out):

watersheds <- c('ANE', 'SAL', 'CER')
assign(paste0(watersheds[1], '_mean'), read.csv(paste0(watersheds[1], '_mean.csv')))

now the next step should be something like this (which works):

cols_dont_want <- c('B1', 'B2', 'B3')
assign(paste0(watersheds[1], '_mean'), SAL_mean[, !names(SAL_mean) %in% cols_dont_want])

but I wanted to ask how to replace "SAL_mean" by using watersheds[1], because this line of code doesn't work:

assign(paste0(watersheds[1], '_mean'), paste0(watersheds[1], '_mean')[, !names(paste0(watersheds[1], '_mean')) %in% cols_dont_want])

I think it treats the "paste0(watersheds[2], '_mean')" as string and not as a name of variable but I haven't been able to find a solution (I tried for example "as.name" function but it gave me an error "object of type 'symbol' is not subsettable")

zx8754
  • 52,746
  • 12
  • 114
  • 209
Marian
  • 31
  • 1
  • 2

3 Answers3

5

Keep dataframes in a list using ?lapply, then it gets easier to carry out same transformations on multiple dataframes in a list, something like:

# set vars
watersheds <- c('ANE', 'SAL', 'CER')
cols_dont_want <- c('B1', 'B2', 'B3')

# result, all dataframes in one list
myList <- lapply(watersheds, function(i){
  # read the file
  x <- read.csv(paste0(i, "_mean.csv"))
  # exclude columns and return
  x[, !colnames(x) %in% cols_dont_want]
} )
zx8754
  • 52,746
  • 12
  • 114
  • 209
  • Thank you, I will try this code but the problem might be that the ultimate goal of my script will be creating and exporting plots - is it doable by using this lapply function? – Marian Oct 09 '17 at 10:53
  • @Marian Yes, it is possible, [here](https://stackoverflow.com/questions/22251928/list-of-plots-using-lapply) is one exmaple. Or we could collapse the list into one dataframe with ID column, then use facet_grid. – zx8754 Oct 09 '17 at 11:03
2

replace

paste0(watersheds[2], '_mean')

with

eval(parse(text = paste0(watersheds[2], '_mean')))

and it should work. Your guess is correct, paste0 just gives you a string but you need to call the variable which is done using eval()

f.lechleitner
  • 3,554
  • 1
  • 17
  • 35
  • Hi, thanks, this works but I don't know why you have minuses...is this beacuse this is considered as bad practise and should be done differently? – Marian Oct 09 '17 at 10:43
  • Yes, I think it is generally considered bad practice. You can read up on it here: https://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse – f.lechleitner Oct 09 '17 at 10:52
  • I didn't think of that when i posted that answer. I've been using eval(parse( myself to dynamically name and save data frames. I'd suggest you go with the answer of @zx8754 – f.lechleitner Oct 09 '17 at 10:58
1

Or you can do it in a for loop (some find the syntax more understandable). It's equivalent to zx8754's solution, except it assigns names to each dataframe as per the OP. It's trivial to modify zx8754's solution do do the same.

watersheds <- c('ANE', 'SAL', 'CER')
cols_dont_want <- c('B1', 'B2', 'B3')
ws.list <- list()

for (i in 1:length(watersheds)) {
    ws.list[[i]] <- read.csv(paste0(watersheds[i], '_mean.csv'))
    names(ws.list)[i] <- paste0(watersheds[i], '_mean')
    ws.list[[i]] <- ws.list[[i]][!names(ws.list[[i]]) %in% cols_dont_want]
}
names(ws.list)
# "ANE_mean" "SAL_mean" "CER_mean"

# If you absolutely want to call the data.frames by their 
# individual names, you can do so after you attach() the list.
attach(ws.list)
ANE_mean
AkselA
  • 8,153
  • 2
  • 21
  • 34
  • Thank you very much, now I am trying to do the rest of my code through the for in loop since I am more accustomed with it. It it possilbe thought that I will have another question later :) – Marian Oct 09 '17 at 11:52