我有许多(600+)文本文件,每个文本文件只包含一列数据,我希望将这些数据读入R中的数据框架中。问题是,我需要将每个文件中的值作为一个单独的列导入,并且每个文件中的值数量并不相等。文本文件都以标题“Area”开头,这是我不需要的(我正在尝试将文件名设置为标题),然后继续使用一列数字(4000 - 10000值)。
Area
0.0034556
0.0002345
....
我最接近的是:
filenames <-dir()
n <- length(filenames)
for (i in 1:n) {data[i] <- read.csv(filenames[i]}
## printing data at this point gives lists for each value of i
然后,我尝试将包含列表的值重新绑定到文件名,以便将其用作单独的列(在变量c下),然后我希望将各个列拼凑到一个dataframe中:
for (i in 1:n) {c[i] <- rbind(filenames[i], data[i])}
当c被打印时,这似乎给出了一个包含两个元素的列表--最后一个文件的名称和它包含的值的数量。
我担心,即使我可以将用read.csv导入的列表绑定到列标题,我仍然无法将其合并到一个数据文件中,因为不同文件之间的值数目不同。我已经看到了将多个文本文件的值合并到一个列中的可能解决方案(并且已经做到了这一点),但是无法找到解决这个问题的解决方案,因为每个导入的文件都需要自己的列在线或漩涡。
如有任何帮助,我将不胜感激!安格斯
发布于 2017-02-09 06:28:40
由于数据量大,我建议使用data.table
。
步骤1:读取一个data.table
中的所有文件
library(data.table)
filenames <-dir()
dt_long <- rbindlist(setNames(lapply(filenames, fread), filenames), idcol = TRUE)
dtl
# .id Area
#1: file1.csv 0.0034556
#2: file1.csv 0.0002345
#3: file2.csv 0.0034556
#4: file2.csv 0.0002345
#5: file2.csv 0.0034556
#6: file2.csv 0.0002345
#7: file2.csv 0.0034556
#8: file2.csv 0.0002345
fread
读取lapply
调用中的每个文件。lapply
是文件名上的一种隐含的for循环,并返回一个列表,其中每个list元素包含一个包含一个文件内容的data.table
。
setNames
用于用相应的文件名重命名每个list元素。
最后,rbindlist
将列表中的单个data.tables
组合成一个大型data.table
。每一行的起源由.id
col标识。
步骤2:将格式重塑为宽格式
通常,我更喜欢使用长格式的数据,因为我可以使用分组函数(例如,by = .id
中的data.table
语法)来同时影响所有文件的数据。
但是,如果您坚持为每个文件设置一个单独的列,则可以将其从宽格式改为长格式:
dt_wide <- dcast(dt_long, rowid(.id) ~ .id, value.var = "Area")
dt_wide
# .id file1.csv file2.csv
#1: 1 0.0034556 0.0034556
#2: 2 0.0002345 0.0002345
#3: 3 NA 0.0034556
#4: 4 NA 0.0002345
#5: 5 NA 0.0034556
#6: 6 NA 0.0002345
请注意,由于文件大小不同而导致的缺失值已由NA
填充。
数据
为了获得一个可重复的示例,我创建了两个虚拟数据文件。
file1.csv
Area
0.0034556
0.0002345
file2.csv
Area
0.0034556
0.0002345
0.0034556
0.0002345
0.0034556
0.0002345
发布于 2017-02-09 06:13:21
也许最简单的方法就是把所有的东西都列在一张清单上。在函数read.csv
中,可以立即用col.names
定义列名。
filenames <-dir()
n <- length(filenames)
data <- list()
for (i in 1:n) {data[[i]] <- read.csv(filenames[i], col.names = filenames[i])}
https://stackoverflow.com/questions/42138252
复制