首页 > 解决方案 > 我应该如何处理合并(完全加入)多个(> 100)CSV 文件与一个公用键但行数不一致?

问题描述

在我深入探讨这个问题之前,这里有一个类似的问题,但还没有解决方案。

因此,我在 R 中工作,并且我的工作目录中有一个名为的文件夹,columns其中包含 198 个类似.csv的文件,其名称格式为 6 位整数(例如 100000),并且不一致地增加(因为这些文件的名称实际上是名称对于每个变量)。

现在,我想完全加入它们,但不知何故,我必须将所有这些文件导入 R,然后加入它们。自然地,我考虑使用列表来包含这些文件,然后使用循环来加入它们。这是我尝试使用的代码:

#These are the first 3 columns containing identifiers
matrix_starter <- read_csv("files/matrix_starter.csv")

## import_multiple_csv_files_to_R
# Purpose: Import multiple csv files to the Global Environment in R

# set working directory
setwd("columns")

# list all csv files from the current directory
list.files(pattern=".csv$") # use the pattern argument to define a common pattern for import files with regex. Here: .csv

# create a list from these files
list.filenames <- list.files(pattern=".csv$")
#list.filenames

# create an empty list that will serve as a container to receive the incoming files
list.data <- list()

# create a loop to read in your data
for (i in 1:length(list.filenames))
{
list.data[[i]] <- read.csv(list.filenames[i])
list.data[[i]] <- list.data[[i]] %>% 
  select(`Occupation.Title`,`X2018.Employment`) %>% 
  rename(`Occupation title` = `Occupation.Title`) #%>% 
  #rename(list.filenames[i] = `X2018.Employment`)
}

# add the names of your data to the list
names(list.data) <- list.filenames

# now you can index one of your tables like this
list.data$`113300.csv`

# or this
list.data[1]

# source: https://www.edureka.co/community/1902/how-can-i-import-multiple-csv-files-into-r

上面的块解决了导入部分。现在我有一个.csv文件列表。接下来,我想加入他们:

for (i in 1:length(list.filenames)){
matrix_starter <- matrix_starter %>% full_join(list.data[[i]], by = `Occupation title`)
}

但是,这并不能很好地工作。我最终得到大约 47,000 行,而我只期望大约 1700 行。请让我知道你的意见。

标签: rtidyverse

解决方案


可以像这样将文件作为列表读入 R 并将文件名作为列包含在内:

files <- list.files(path = path,
                    full.names = TRUE,
                    all.files = FALSE)
files <- files[!file.info(files)$isdir]

data <- lapply(files,
               function(x) {
                 data <- read_xls(
                   x,
                   sheet = 1
                 )
                 data$File_name <- x
                 data
                 })

我现在假设您所有的 excel 文件都具有相同的结构:相同的列和列类型。如果是这种情况,您可以使用它dplyr::bind_rows来创建一个组合数据框。您当然可以遍历列表并 left_join 列表元素。例如通过使用Reduceand merge

根据 mihndang 的评论进行更新。当您说:有没有办法使用文件名来命名列并且不包括文件名列时,这就是您所追求的吗?

library(dplyr)
library(stringr)

path <- "./files"
files <- list.files(path = path,
                    full.names = TRUE,
                    all.files = FALSE)
files <- files[!file.info(files)$isdir]

data <- lapply(files,
               function(x) {
                 read.csv(x, stringsAsFactors = FALSE)
               })

col1 <- paste0(str_sub(basename(files[1]), start = 1, end = -5), ": Values")
col2 <- paste0(str_sub(basename(files[1]), start = 1, end = -5), ": Character")
df1 <- data[[1]] %>%
  rename(!!col1 := Value,
         !!col2 := Character)

我在./files:file1.csvfile2.csv. 我将它们读入列表。我提取第一个列表元素(DF)并计算出变量中的列名。然后我通过将两个变量传递给 DF 中的列来重命名它们。列名包括文件名。结果:

> View(df1)
> df1
   file1: Values file1: Character
1              1                a
2              2                b
3              3                c
4              4                d
5              5                e
6              6                f
7              7                g
8              8                h
9              9                i
10            10                j

推荐阅读