【问题标题】:How to simultaneously merge multiple csv files and summarize several variables per group如何同时合并多个 csv 文件并汇总每个组的多个变量
【发布时间】:2021-04-10 16:22:09
【问题描述】:

这是我第二次尝试在这里提出问题 - 希望这一次我能清楚地表达自己并符合本网站上的建议。 问题是:我有一个关于某些公司及其总部的数据集。数据的结构对我来说有点混乱(请参阅下面的链接) - 更成问题的是我有 2003 年、2007 年、2011 年、2015 年和 2019 年的 15 个单独的数据(每个三个 csv 文件年,因为我猜的大小)。

出于这个问题的目的,我将三个文件合并为一个(针对 2003 年)。

现在,我想要的是:1) 合并所有 15 个文件,然后从那里 2) 生成一组变量,这些变量将指示每个国家和年份的公司总数 [请注意,虽然年份变量不包括在内作为变量]。

由于我有四个主要地址的数据,我想根据 (1, 2, 3, 4) 的顺序创建单独的“总和变量”,此外,还有一个不需要的变量考虑国家的顺序。

只是举一个我希望它看起来如何的例子:

country year    total_c1    total_c2   ...
USA     2003        100         100
USA     2007        150         120
CAN     2003        50          50
CAN     2007        100         60

我打算将此数据与我拥有的面板数据(国家年份数据)合并。

请点击链接访问数据。 Data sample for 2003。 第一个变量表示公司的 ID。 第二个(country_1)表示第一个地址的国家。第三个(country_2)表示第二个地址的国家,依此类推。之后,出现一堆变量(超过 2800 个)表示数据集中的一家公司。

现在,我想在 R 中尝试执行此操作(而不是手动执行)。感谢 @Duck 帮助我完成合并部分。

myfun <- function(df)
{
  #Code
  new <- df %>%
    pivot_longer(starts_with('country')) %>%
    group_by(name) %>%
    summarise_all(sum,na.rm=T)
  return(new)
}
#Load files
myfiles <- list.files(pattern = '.csv')

#List of files
L <- lapply(myfiles, read.csv)

#Apply function
L <- lapply(L,myfun)

# turn to a df
df <- as.data.frame(L)

但这对我来说并不奏效,因为我无法弄清楚数据来自哪一年。相反,我将文件合并了一年(例如 2003 年)并尝试通过运行以下命令来创建我想要的变量:

  df2<- df %>%
  mutate(Total_c1 = select(., A2654:U9340) %>% rowSums(na.rm = TRUE))

  df3<–df2 %>% group_by(country_1) %>%
  summarise(Total_c1=sum(Total_c1,na.rm = T)

我在这里卡住了。任何可以带我从这里(并从右侧开始)前进的建议将不胜感激!

【问题讨论】:

  • 文件名中有年份吗?如果是这样,那么您必须从文件名中提取年份(使用正则表达式或位置),然后在将行绑定在一起之前使用 lapply 或 map 为列表中的每个表添加一列。
  • @Ferenc:检查这个解决方案,看看它是否有帮助stackoverflow.com/a/48105838/786542

标签: r dplyr data.table tidyverse


【解决方案1】:

假设您要合并的所有 csv 文件都在工作目录本身中,您可以尝试以下代码部分。

library(tidyverse)

myfiles <- list.files(pattern = '.csv')

map_df(myfiles, function(x) {
  year_number <- readr::parse_number(x)
  df <- read.csv2(x)
  df %>%
    mutate(Total = rowSums(select(., -(1:5)), na.rm = TRUE)) %>%
    pivot_longer(cols = starts_with('country')) %>%
    group_by(name, value) %>%
    summarise(Total  = sum(Total)) %>%
    pivot_wider(names_from = name, values_from = Total) %>%
    mutate(year = year_number)
}) %>%
  arrange(country, year) -> result

result

【讨论】:

  • 谢谢罗纳克。我有这个 A tibble:0 x 0 运行代码时。有些不对劲。 df 也不包含 year 变量。
  • myfiles 返回什么?
  • [1] "UIA data 2003 part 1.CSV" "UIA data 2003 part 2.CSV" "UIA data 2003 part 3.CSV" "UIA data 2007
  • 当我运行最后一行时,我得到这个:Error in mutate_impl(.data, dots, caller_env()) : variable names are limited to 10000 bytes
  • 所以你有多个同一年的文件?读取数据是否适用于 1 个文件? df &lt;- read.csv2(myfiles[1]) 可以正常工作吗?你能检查df 是否符合预期吗?之后,首先尝试仅使用 2 个文件。 myfiles &lt;- myfiles[1:2]
【解决方案2】:

您已在此处就不同问题寻求帮助。我只回答一个。使用 data.table 库,可以有效地读取同一目录中具有相同或几乎相同列标题的许多 CSV。这会产生一个对象 (l1):

library(data.table)
# setDTthreads() # use some appropriate integer
# unzip all the files you want row bound .... to this directory
setwd("D:/Politics/General.2020/BallotReturnStats/11.24.2020")
l1 <- as.data.table({})
for(i in dir()) {l1 <- rbind(l1,fread(i),fill=TRUE)}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2023-02-14
    • 2021-09-27
    相关资源
    最近更新 更多