Question: Using variables into data frame names in R
0
gravatar for Fersal
21 days ago by
Fersal10
Fersal10 wrote:

I have several text files (animal_grp1.txt, animal_grp2.txt...animal_grp50.txt) I want to import and modify in R by using a for loop.

I usually do this:

lote1 <- read.delim("animal_grp1.txt", header = T, sep = "\t")
lote1 <- lote1[c(2,5,7)]
names(lote1) <- c("ID", "race", "age")

but it is not efficient to repeat this code 50 times, so I was thinking that maybe by using a loop it would be more efficient.

Something like that:

animals <-c(1,2,3,4,5)
for(i in animal) {
 lote[i] <- read.delim("animal_grp[i].txt", header = T, sep = "\t")
 lote[i] <- lote[i][c(2,5,7)] 
 names(lote[i]) <- c("ID", "race", "age") 
}

It seems it is not so simple as I thought. Any help?

Thanks

loop R • 138 views
ADD COMMENTlink modified 21 days ago by russhh3.9k • written 21 days ago by Fersal10

Sorry, I didn't see that you wanted to produce lote1, lote2, ... each as separate variables. If you do this it will cripple your work at a later stage - if it's inefficient to write 50 different lines of code to read in the data, it'll be just as inefficient to write 50 different lines to analyse the imported data. If you've got some large number of homogeneously structured files, and you're not up-to-speed with map/lapply in R, you'd be better constructing a list

lote <- vector(n = length(animals), mode = "list")

In the list lote[[5]] would return the value stored in the 5th element and lote[[7]] <- some_value would store some_value in the 7th entry.

So you could modify your code:

for (i in animals) { file_name <- paste0("animal_grp", i, ".txt") df <- read.delim(file_name, header = TRUE, sep = "\t")[c(2,5,7)] names(df) <- c("ID", "race", "age") lote[[i]] <- df }

ADD REPLYlink written 21 days ago by russhh3.9k
2
gravatar for b.nota
21 days ago by
b.nota5.0k
Netherlands
b.nota5.0k wrote:

You are almost there, you need to use the paste command to incorporate the i number.

animals <-c(1,2,3,4,5)

for(i in animals) {
  fileName <- paste0("animal_grp",i ,".txt")
  lote <- read.delim(fileName, header = T, sep = "\t")
  lote <- lote[c(2,5,7)] 
  names(lote) <- c("ID", "race", "age")
  assign(paste0("lote", i), lote)
}
ADD COMMENTlink modified 21 days ago • written 21 days ago by b.nota5.0k

Thanks for your answer. I got it with your suggestion. The only thing is that in addition of lote1, lote2, and lote3, I am also getting an extra data frame lote without number.

ADD REPLYlink modified 21 days ago • written 21 days ago by Fersal10

I think you need to learn more on R and programmation in general. lote variable is declared in your loop and his still in the scope of your session.

ADD REPLYlink modified 21 days ago • written 21 days ago by Nicolas Rosewick6.7k

You'll also find i and fileName, just like lote these are temp objects only used in the loop. If that bothers you, you can add the following line after the loop or at the end of the loop as the last line (after assign..., but before }).

rm(lote, i, fileName)
ADD REPLYlink modified 21 days ago • written 21 days ago by b.nota5.0k
0
gravatar for russhh
21 days ago by
russhh3.9k
UK, U. Glasgow
russhh3.9k wrote:

Install tidyverse Then map over your filenames

library(tidyverse)
files <- dir(pattern = "animal_grp[[:digit:]]\+.txt") # I think

as.list(files) %>%
purrr::map(read_tsv, col_types = cols()) %>%
purrr::map(c(2,5,7)) %>%
purrr::map(set_colnames, c("ID", "race", "age"))

Sorry if this doesn't work first time I can't debug it at the moment

ADD COMMENTlink written 21 days ago by russhh3.9k
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1743 users visited in the last hour