11

I have two types of files in my directory. Each type has either the text "Drug_Rep" in it or if its not there it means its a control file. Drug data has replicates which can vary in number and so does the control. I am reading the files in a for loop as follows. I want to name my dataframes as X_Drug_Rep1 and then the next as X_Drug_Rep2 and so on...and save the dataframe for further processing. Do the same for controls...X_CONTROL_Rep1...X_CONTROL_Rep2...and so on. What is the syntax to save my data into dataframes because i need to do some merges and calculations later on the drug replicate dataframes and controls separately. paste on the left side of assignment does not seem to work. Any suggestions?

for (f in 1:length(fileList)){
    fileName <- fileList[f]
    X <-read.xls(fileName)

    if(regexpr("Drug_Rep", fileName)[1]>0){
      print("DRUG")
      print(fileName)
      paste(X_Drug_Rep,i)<-X
      i=i+1
    }
    else{
      print("CONTROL")
      print(fileName)
      paste(X_CONTROL,j)<-X
      j=j+1
    }
  }
RnD
  • 1,172
  • 4
  • 15
  • 25
  • 7
    this gets asked a lot. The technical answer is to use `assign` but a preferred approach is to build a list (two in your case.) – flodel Jun 22 '13 at 22:29
  • i did click on the link but still i am not able to get the assign syntax right...is this what i do: assign(paste(X_Drug_Rep,i, sep='_'),i) – RnD Jun 22 '13 at 22:36
  • 2
    `assign(paste("X_Drug_Rep", i, sep = '_'), X)` – flodel Jun 22 '13 at 22:41
  • thanks! i do the following:assign(paste("X_Drug_Rep", i, sep = '_'), X) as you suggested but how can i access my new dataframe called X_Drug_Rep_1 – RnD Jun 22 '13 at 23:30
  • 1
    `X_Drug_Rep_1` is an object so you can just access it like that, by typing `X_Drug_Rep_1`. If you mean how can you access it via a variable like `i <- 1`, this also gets asked a lot. The technical answer is to use `get` but a preferred approach is to have all of your objects in a list to start with. Hence my recommendation again: use a list! – flodel Jun 22 '13 at 23:33
  • when i type print(X_Drug_Rep_1), i get the error: Error in print(X_Drug_Rep_1) : object 'X_Drug_Rep_1' not found...so this is what i was asking. The reason i want X_Drug_Rep_1,X_Drug_Rep_2,X_Drug_Rep_3 is that i will do a merge on my dataframes later in the code.Thanks – RnD Jun 22 '13 at 23:50
  • 1
    As mentioned above, you _can_ use `assign` for this purpose but you _should not_. You can assign names to a list _after_ it's been constructed via `names(myList) <- ...`. This is much clearer, less error prone, and will result in much shorter code. – joran Jun 23 '13 at 02:45

1 Answers1

24

OP is really struggling so instead of a long comment, I'll show him here. Don't care if this gets closed.

The technical (don't do that answer) would be to use assign:

i <- 1
j <- 1
for (f in 1:length(fileList)){
    fileName <- fileList[f]
    X <-read.xls(fileName)

    if(grepl("Drug_Rep", fileName)) {
      print("DRUG")
      print(fileName)
      assign(paste("X_Drug_Rep", i, sep = '_'), X)
      i <- i+1
    } else {
      print("CONTROL")
      print(fileName)
      assign(paste("X_CONTROL", i, sep = '_'), X)
      j <- j+1
    }
  }

But as we recommended, you should use lists instead. Using a for loop, it would look like this:

X_Drug_Rep <- list()
X_CONTROL  <- list()
i <- 1
j <- 1
for (f in 1:length(fileList)){
    fileName <- fileList[f]
    X <-read.xls(fileName)

    if(grepl("Drug_Rep", fileName)) {
      print("DRUG")
      print(fileName)
      X_Drug_Rep[[i]] <- X
      i <- i+1
    } else {
      print("CONTROL")
      print(fileName)
      X_CONTROL[[j]] <- X
      j <- j+1
    }
  }

Finally, how your code would look like without a for loop:

drug.rep.files <- grep("Drug_Rep", fileList, value = TRUE)
control.files  <- grep("Drug_Rep", fileList, value = TRUE, invert = TRUE)

X_Drug_Rep <- lapply(drug.rep.files, read.xls)
X_CONTROL  <- lapply(control.files, read.xls)

Much shorter, no?! Again, this creates two lists. For example, instead of X_Drug_Rep_1, you would access the first Drug_Rep item by doing X_Drug_Rep[[1]].

flodel
  • 87,577
  • 21
  • 185
  • 223