#r #rbind
Вопрос:
У меня есть имена <InputData>.<TestName>.csv
файлов, и я хотел бы построить графики для каждого теста. Лучший способ, который я вижу для этого, — это создать одну таблицу R для каждого имени теста. Каждый тест создает одни и те же столбцы данных, поэтому я хотел бы собрать все данные для каждого теста в R-базу данных с дополнительным столбцом для входных данных.
Я бы хотел сделать:
read.tables(c("B217.SE.csv", "C10.SE.csv"), sep=",")
производит (например):
Filename col1 col2
1 B217.SE.csv 1 2
2 B217.SE.csv 2 4
3 C10.SE.csv 3 1
4 C10.SE.csv 4 5
Как правильно это сделать? Какая-то существующая функция, о которой я не знаю? Написание его на языке R с использованием цикла for?
Ответ №1:
Я не могу проверить это на ваших данных, но вы захотите использовать apply
функцию типа, подобную этой:
data <- do.call("rbind", lapply(c("file1", "file2"), function(fn)
data.frame(Filename=fn, read.csv(fn)
))
Или вы можете упростить его с помощью plyr
. Вот примерное моделирование того, как это будет работать (с использованием фреймов данных вместо файлов):
> df1 <- data.frame(c1=1:5, c2=rnorm(5))
> df2 <- data.frame(c1=3:7, c2=rnorm(5))
В этом случае я буду использовать get
вместо read.csv
:
> data <- ldply(c("df1", "df2"), function(dn) data.frame(Filename=dn, get(dn)))
> data
Filename c1 c2
1 df1 1 -0.15679732
2 df1 2 -0.19392102
3 df1 3 0.01369413
4 df1 4 -0.73942829
5 df1 5 -1.27522427
6 df2 3 -0.33944114
7 df2 4 -0.12509065
8 df2 5 0.11225053
9 df2 6 0.88460684
10 df2 7 -0.70710520
Редактировать
Следуя предложению Марека, вы можете либо перезаписать, либо создать свою собственную функцию:
read.tables <- function(file.names, ...) {
require(plyr)
ldply(file.names, function(fn) data.frame(Filename=fn, read.csv(fn, ...)))
}
data <- read.tables(c("filename1.csv", "filename2.csv"))
Комментарии:
1. На пути к полному обобщению:
read.tables <- function(files, ...) ldply(files, function(f) data.frame(Filename=f, read.csv(f,...)))
(затем мы можем передать аргументыread.csv
)2. Обычно я делаю что — то вроде
names(file.names) <- basename(file.names); ldply(file.names, read.csv)
-тогда вам не нужно добавлять столбец имени файла самостоятельно.
Ответ №2:
Попробуйте это:
## take files.
files <- list.files(pattern=".csv")
## read data using loop
DF <- NULL
for (f in files) {
dat <- read.csv(f, header=T, sep="t", na.strings="", colClasses="character")
DF <- rbind(DF, dat)
}
Комментарии:
1. Чтобы отслеживать данные по имени файла, я стремлюсь получить имя из
f
переменной. Я использовалtools
пакет для получения имени файла с помощьюfile_path_sans_ext
. Единственное предостережение заключается в том, что он выводит данные с векторным идентификатором col/строки (размер). Как я могу просто узнать только имя?