首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个R函数,它迭代data.frame,打开/合并文件,并返回另一个数据帧。

一个R函数,它迭代data.frame,打开/合并文件,并返回另一个数据帧。
EN

Stack Overflow用户
提问于 2012-01-07 01:00:16
回答 2查看 267关注 0票数 1

我想知道如何使用像ddply,ldply,dlply这样的高阶函数来解决以下问题,并避免使用有问题的for循环。

问题:我有一个表示加载到data.frame中的数据集的.csv文件,每一行都包含一个目录的路径,在这个目录中,更多的信息存储在文件中。我想使用datas.frame中的目录信息打开该目录中的文件(“file1.txt”,"file2.txt"),合并它们,然后将每个条目的合并文件合并到一个大型数据帧中。如下所示: df =

代码语言:javascript
复制
entryName,dir
1,/home/guest/data/entry1
2,/home/guest/data/entry2
3,/home/guest/data/entry3
4,/home/guest/data/entry4

我想要做的是对数据帧应用一个函数,该数据帧获取目录,附加几个文件名"file1.txt","file.txt",然后根据给定的字段将这两个文件合并在一起。

例如,file1.txt可以是:

代码语言:javascript
复制
entry,subEntry,value
1,A,2
1,B,3
1,C,4
1,D,5
1,E,3
1,F,3

例如,file2.txt可以是:

代码语言:javascript
复制
entry,subEntry,value
1,A,8
1,B,7
1,C,8
1,D,9
1,E,8
1,F,7

输出将如下所示:

代码语言:javascript
复制
entryName,subEntry,valueFromFile1,valueFromFile2
1,A,2,8
1,B,3,7
1,C,4,8
1,D,5,9
1,E,3,8
1,F,3,7
2,A,4,8
2,B,5,9
2,C,6,7
2,D,3,7
2,E,6,8
2,F,5,9

现在我使用的是for循环,但出于显而易见的原因,我想使用一个更高阶的函数。这是我到目前为止所知道的:

代码语言:javascript
复制
allCombined <- data.frame()
df <- read.csv(file="allDataEntries.csv",header=true) 
numberOfEntries = <- dim(df)[1]

for(i in 1:numberOfEntries){ 
  dir <- df$dir[i]
  file1String <- paste(dir,"/file1.txt",sep='') 
  file2String <- paste(dir,"/file2.txt",sep='')
  file1.df <- read.csv(file=file1String,header=TRUE)
  file2.df <- read.csv(file=file2String,header=TRUE)
  localMerged <- merge(file1.df,file2.df, by="value")
  allCombined <- rbind(allCombined,localMerged) 
} 
#rest of my analysis...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-07 02:25:08

这里有一种方法可以做到。其思想是创建一个包含所有文件内容的列表,然后使用Reduce通过公共列entrysubEntry按顺序合并它们。

代码语言:javascript
复制
# READ DIRECTORIES, FILES AND ENTRIES
dirs    <- read.csv(file = "allDataEntries.csv", header = TRUE, as.is = TRUE)$dir
files   <- as.vector(outer(dirs, c('file.txt', 'file2.txt'), 'file.path'))
entries <- lapply(files, 'read.csv', header = TRUE)

# APPLY CUSTOM MERGE FUNCTION TO COMBINE ENTRIES
merge_by <- function(x, y){
  merge(x, y, by = c('entry', 'subEntry'))
}
Reduce('merge_by', entries)
票数 2
EN

Stack Overflow用户

发布于 2012-01-07 03:00:55

我还没有对此进行测试,但看起来应该可以工作。匿名函数从df中获取一行,读入两个相关的文件,并通过值将它们合并在一起。使用ddply将获取这些数据帧,并通过rbinding生成一个数据帧(因为请求的输出是一个数据帧)。它确实假设df中没有重复entryName。如果是,您可以添加一个唯一的行进行分组。

代码语言:javascript
复制
ddply(df, .(entryName), function(DF) {
  dir <- df$dir
  file1String <- paste(dir,"/file1.txt",sep='') 
  file2String <- paste(dir,"/file2.txt",sep='')
  file1.df <- read.csv(file=file1String,header=TRUE)
  file2.df <- read.csv(file=file2String,header=TRUE)
  merge(file1.df,file2.df, by="value")
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8761472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档