За петлевой вопрос в R - PullRequest
3 голосов
/ 17 января 2011

Надеюсь, я смогу объяснить свой вопрос достаточно хорошо, чтобы получить ответ - любая помощь будет оценена.

У меня есть номер файла данных, который мне нужно объединить в один.Для этого я использую цикл for и добавляю столбец, в котором указано, какой это файл.

В этом случае имеется 6 файлов с до 100 записями данных в каждом.

Когда есть6 файлов У меня нет проблем с запуском этого.

Но когда их меньше, у меня возникает проблема.

Я бы хотел использовать цикл for для проверки файлов.и использовать переменную цикла for для сборки вектора, который ссылается на существующие файлы.

Кажется, я не могу получить новую переменную для объединения нового значения переменной цикла for, когда она проходит через цикл.

Вот пример кода, который я написал до сих пор.

for ( rloop1 in 1 : 6) {
ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
if (file.exists(ReadFile))
**files_found <- c(rloop1)**
}

Я ищу, чтобы files_found содержал те файлы, где 1 ... 6 действительны для найденных файлов..

С уважением, Стив

Ответы [ 3 ]

7 голосов
/ 17 января 2011

Вероятно, было бы лучше перечислить файлы, которые вы хотите загрузить, а затем зациклить этот список, чтобы загрузить их.list.files твой друг здесь.Мы можем использовать регулярное выражение для вывода списка только тех файлов, которые заканчиваются на "_Stats.csv".Например, в моем текущем рабочем каталоге у меня есть следующие файлы:

$ ls | grep Stats
bar_Stats.csv
foobar_Stats.csv
foobar_Stats.csv.txt
foo_Stats.csv

Только три из них являются CSV-файлами, которые я хочу загрузить (файл .txt не соответствует показанному вами шаблону).Мы можем получить эти имена файлов, используя list.files():

> list.files(pattern = "_Stats.csv$")
[1] "bar_Stats.csv"    "foo_Stats.csv"    "foobar_Stats.csv"

Затем вы можете зациклить это и прочитать файлы. Что-то вроде:

fnames <- list.files(pattern = "_Stats.csv$")
for(i in seq_along(fnames)) {
    assign(paste("file_", i, sep = ""), read.csv(fnames[i]))
}

Это создаст сериюобъекты file_1, file_2, file_3 и т. д. в глобальном рабочем пространстве.Если вы хотите, чтобы файлы в списке, вы могли бы вместо lapply вместо fnames:

lapply(fnames, read.csv)

и, если необходимо, do.call может помочь объединить файлы из списка:

do.call(rbind, lapply(fnames, read.csv))
4 голосов
/ 17 января 2011

Существует гораздо более короткий способ сделать это, используя list.files (), как показал Хенрик.Если вы не знакомы с регулярными выражениями (см. ?regex), вы можете сделать.

n <- 6
Fnames <- paste(1:n,SampleName,"_",FileName,"Stats.csv",sep="")
Filelist <- Fnames[file.exists(Fnames)]

, что совершенно эквивалентно.И paste, и file.exists являются векторизованными функциями, так что вам лучше использовать это.Для цикла нет необходимости.

Чтобы получить количество имен файлов (при условии, что это единственные цифры), вы можете сделать:

gsub("^[:digit:]","", Filelist)

См. Также ?regex

3 голосов
/ 17 января 2011

Я думаю, что есть лучшие решения (например, вы могли бы использовать list.files() для сканирования папки, а затем зациклить длину возвращаемого объекта), но это должно (я не пробовал) сделать свое дело (используя Ваш пример кода):

files.found <- ""    
for (rloop1 in 1 : 6) {
    ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
    if (file.exists(ReadFile)) files_found <- c(files.found, rloop1)
}

Кроме того, вы можете получить fileNames (кроме их индекса) через:

files.found <- ""    
for (rloop1 in 1 : 6) {
    ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
    if (file.exists(ReadFile)) files_found <- c(files.found, ReadFile)
}

Наконец, в вашем случае list.files может выглядеть примерно так:

files.found <- list.files(pattern = "[[:digit:]]_SampleName_FileName_Stats.csv")
...