R 将多个文件合并为 1 个数据框并保留所有值
R merge multiple files into 1 dataframe and keep all values
我有 6 个多个文件,每个文件只有 1 列名称。我想读取所有这些文件并将它们合并到 1 个数据框中,这样它看起来像这样:
file1 file2 file3 file4 file5 file6
adam adam adam adam adam adam
Roy NA Roy Roy NA NA
NA Sam Sam NA NA NA
结果数据帧的 colnames
应该代表实际的文件名。假设我读取的文件名为 file1.txt
、file2.txt
等等..
任何帮助将不胜感激。
到目前为止我一直在尝试什么:
multmerge = function(mypath){
+ filenames=list.files(path=mypath, full.names=TRUE, pattern = "\.txt$")
+ datalist = lapply(filenames, function(x){read.csv(file=x,header=F)})
+ Reduce(function(x,y) {merge(x,y, all.x=T)}, datalist)}
> mymergeddata = multmerge("/Path/To/The/Folder/Having/All/Files")
> dim(mymergeddata)
[1] 11508 1
如此处所示,它将所有值 (names
) 组合在一列中..
这是使用来自 data.table
的 rbindlist 和 dcast 执行此操作的一种方法
library(data.table)
file_list <- list.files("c:/temp/files/",full.names = TRUE)
import_files <- lapply(file_list,read.csv,stringsAsFactors =FALSE)
rbinded_files <- na.omit(rbindlist(import_files,idcol="file"))
dcast(rbinded_files,file1 ~file,fun=max, na.rm=TRUE)
file1 1 2 3 4 5 6
1 adam adam adam adam adam adam adam
2 Roy Roy <NA> Roy Roy <NA> <NA>
3 Sam <NA> Sam Sam <NA> <NA> <NA>
如果需要,您可以删除第一列。
另一个解决方案purrr::map
files <- list.files("/path/",full.names = TRUE)
combinedDF <- files %>% map(read.csv, stringsAsFactors=FALSE, col.names=files) %>%
reduce(cbind)
这可能不是最有效的,但函数应该可以解决问题,我很乐意听到改进函数的方法,因为我是堆栈新手:
library(data.table); library(tidyverse)
multmerge <- function(dir) {
# Load files and bind columns
full_dir_filenames <- list.files(path = dir, full.names = TRUE, pattern = "\.txt$")
datalist <- lapply(full_dir_filenames, read_csv, col_names = FALSE) %>%
lapply(t) %>%
lapply(as.tibble)
df <- bind_cols(datalist)
# Append the column names
file_names <- list.files(path = dir, full.names = FALSE, pattern = "\.txt$")
col_names <- tstrsplit(file_names, split = "[.]")[[1]]
colnames(df) <- col_names
df
}
multmerge()
这是您的函数的另一个版本,可提供您要求的输出...
multmerge <- function(mypath){
filenames <- list.files(path=mypath, full.names=TRUE, pattern = "\.txt$")
datalist <- lapply(filenames, function(x){
df <- read.csv(file=x,header=F,stringsAsFactors = FALSE)
df[,2] <- gsub("\.txt","",basename(x))
return(df)})
namesdf <- do.call(rbind,datalist)
output <- as.data.frame.matrix(table(namesdf$name,namesdf$file))
for(j in 1:nrow(output)){
output[j,] <- ifelse(as.numeric(output[j,])==0,NA,row.names(output)[j])
}
return(output)
}
我有 6 个多个文件,每个文件只有 1 列名称。我想读取所有这些文件并将它们合并到 1 个数据框中,这样它看起来像这样:
file1 file2 file3 file4 file5 file6
adam adam adam adam adam adam
Roy NA Roy Roy NA NA
NA Sam Sam NA NA NA
结果数据帧的 colnames
应该代表实际的文件名。假设我读取的文件名为 file1.txt
、file2.txt
等等..
任何帮助将不胜感激。
到目前为止我一直在尝试什么:
multmerge = function(mypath){
+ filenames=list.files(path=mypath, full.names=TRUE, pattern = "\.txt$")
+ datalist = lapply(filenames, function(x){read.csv(file=x,header=F)})
+ Reduce(function(x,y) {merge(x,y, all.x=T)}, datalist)}
> mymergeddata = multmerge("/Path/To/The/Folder/Having/All/Files")
> dim(mymergeddata)
[1] 11508 1
如此处所示,它将所有值 (names
) 组合在一列中..
这是使用来自 data.table
的 rbindlist 和 dcast 执行此操作的一种方法library(data.table)
file_list <- list.files("c:/temp/files/",full.names = TRUE)
import_files <- lapply(file_list,read.csv,stringsAsFactors =FALSE)
rbinded_files <- na.omit(rbindlist(import_files,idcol="file"))
dcast(rbinded_files,file1 ~file,fun=max, na.rm=TRUE)
file1 1 2 3 4 5 6
1 adam adam adam adam adam adam adam
2 Roy Roy <NA> Roy Roy <NA> <NA>
3 Sam <NA> Sam Sam <NA> <NA> <NA>
如果需要,您可以删除第一列。
另一个解决方案purrr::map
files <- list.files("/path/",full.names = TRUE)
combinedDF <- files %>% map(read.csv, stringsAsFactors=FALSE, col.names=files) %>%
reduce(cbind)
这可能不是最有效的,但函数应该可以解决问题,我很乐意听到改进函数的方法,因为我是堆栈新手:
library(data.table); library(tidyverse)
multmerge <- function(dir) {
# Load files and bind columns
full_dir_filenames <- list.files(path = dir, full.names = TRUE, pattern = "\.txt$")
datalist <- lapply(full_dir_filenames, read_csv, col_names = FALSE) %>%
lapply(t) %>%
lapply(as.tibble)
df <- bind_cols(datalist)
# Append the column names
file_names <- list.files(path = dir, full.names = FALSE, pattern = "\.txt$")
col_names <- tstrsplit(file_names, split = "[.]")[[1]]
colnames(df) <- col_names
df
}
multmerge()
这是您的函数的另一个版本,可提供您要求的输出...
multmerge <- function(mypath){
filenames <- list.files(path=mypath, full.names=TRUE, pattern = "\.txt$")
datalist <- lapply(filenames, function(x){
df <- read.csv(file=x,header=F,stringsAsFactors = FALSE)
df[,2] <- gsub("\.txt","",basename(x))
return(df)})
namesdf <- do.call(rbind,datalist)
output <- as.data.frame.matrix(table(namesdf$name,namesdf$file))
for(j in 1:nrow(output)){
output[j,] <- ifelse(as.numeric(output[j,])==0,NA,row.names(output)[j])
}
return(output)
}