【问题标题】:Sum up tables results from multiple sheets into one table in R将多张表格中的表格结果汇总到R中的一张表格中
【发布时间】:2021-08-13 23:05:59
【问题描述】:

我正在阅读具有多张工作表的 excel 文件。

 file_to_read <- "./file_name.xlsx"
 
 # Get all names of sheets in the file
 sheet_names <- readxl::excel_sheets(file_to_read)
 
 # Loop through sheets
 L <- lapply(sheet_names, function(x) {
 all_cells <-
 tidyxl::xlsx_cells(file_to_read, sheets = x)
})

L 这里有所有的床单。现在,我需要从每张工作表中获取数据,以将所有列和行合并到一个文件中。准确的说,我想将数据中匹配的列和行汇总到一个文件中。

我会举个简单的例子来说明清楚。

例如,这张表在一张纸上,

df1 <- data.frame(x = 1:5, y = 2:6, z = 3:7)
rownames(df1) <- LETTERS[1:5]
df1
M x y z
A 1 2 3
B 2 3 4
C 3 4 5
D 4 5 6
E 5 6 7

下一张表中的第二个表格,

df2 <- data.frame(x = 1:5, y = 2:6, z = 3:7, w = 8:12)
rownames(df2) <- LETTERS[3:7]
df2
M x y z  w
C 1 2 3  8
D 2 3 4  9
E 3 4 5 10
F 4 5 6 11
G 5 6 7 12  

我的目标是从一个 excel 文件中组合(求和)所有 100 个表中的匹配记录,得到一个包含每个值总和的大表。

决赛桌应该是这样的:

M x y  z   w
A 1 2  3   0
B 2 3  4   0
C 4 6  8   8
D 6 8  10  9
E 8 10 12 10
F 4 5  6  11
G 5 6  7  12

有没有办法在 R 中实现这一点?我不是 R 方面的专家,但我希望我能知道如何阅读所有表格并进行求和,然后将输出保存到文件中。

谢谢

【问题讨论】:

  • 请不要将数据发布为图片。看看如何创建一个great reproducible example 来显示数据。
  • @AnilGoyal 谢谢。它没有回答我的问题。我正在努力从多张表格中读取 100 张表格,然后汇总到一张表格中。
  • @MartinGal 我更新了问题并添加了更多可重现的代码。谢谢!
  • @AmalNasir,你给出的例子有行名。我将这些名称创建到“ID”列中。如果您收到未找到 id 列的错误,则仅表示您的实际数据没有行名。现在首先在您的 R 控制台/IDE 中尝试示例数据上的代码。如果它在示例上运行,则仅表示您的数据与您共享的数据不同。如果它仍然没有运行,那么问题可能在其他地方,例如未加载的包等。在这种情况下,您必须自己先找到问题所在。祝你好运。
  • 根据已编辑的问题查看已编辑的答案。您的 toy_data 创建不正确,因为您首先创建行名,但再次编辑数据以删除行名。我还观察到,尽管您将问题更改了 5-6 次,但您没有对下面给出的任何答案进行投票。 Upvote 是对回答者的感谢,它有助于对好的内容/未来参考进行分类。

标签: r excel contingency


【解决方案1】:

正如您所说,您有数百张工作表,建议您应该将所有这些都导入一个列表中,例如 R 中的 my.list(根据建议的 this linkthis readxl documentation)并遵循此策略每两个dfs一一绑定

df1 <- read.table(text = 'M x y z
A 1 2 3
B 2 3 4
C 3 4 5
D 4 5 6
E 5 6 7', header = T)
df2 <- read.table(text = 'M x y z  w
C 1 2 3  8
D 2 3 4  9
E 3 4 5 10
F 4 5 6 11
G 5 6 7 12', header = T)

library(tibble)
library(tidyverse)

my.list <- list(df1, df2)

map_dfr(my.list, ~.x)
#>    M x y z  w
#> 1  A 1 2 3 NA
#> 2  B 2 3 4 NA
#> 3  C 3 4 5 NA
#> 4  D 4 5 6 NA
#> 5  E 5 6 7 NA
#> 6  C 1 2 3  8
#> 7  D 2 3 4  9
#> 8  E 3 4 5 10
#> 9  F 4 5 6 11
#> 10 G 5 6 7 12
map_dfr(my.list , ~ .x) %>%
  group_by(M) %>%
  summarise(across(everything(), sum, na.rm = T))
#> # A tibble: 7 x 5
#>   M         x     y     z     w
#>   <chr> <int> <int> <int> <int>
#> 1 A         1     2     3     0
#> 2 B         2     3     4     0
#> 3 C         4     6     8     8
#> 4 D         6     8    10     9
#> 5 E         8    10    12    10
#> 6 F         4     5     6    11
#> 7 G         5     6     7    12

reprex package (v2.0.0) 于 2021 年 5 月 26 日创建

【讨论】:

  • 谢谢!我得到了这个错误。错误:必须按在.data 中找到的变量分组。 * 未找到列 id。我应该改用哪个变量?
  • 用阅读表更新了问题。
  • 这也有效!谢谢你。但这并没有帮助我阅读多张纸。非常感谢您的帮助!
【解决方案2】:

一种可行的方法是以下步骤:

  • 将每张纸读入一个列表
  • 将每张工作表转换为长格式
  • 绑定到单个数据框
  • 对该长数据帧进行求和和分组
  • 转换回表格格式

这应该适用于 N 个工作表,这些工作表中的行标题和列标题任意组合。例如

file <- "D:\\Book1.xlsx"
sheet_names <- readxl::excel_sheets(file)
sheet_data <- lapply(sheet_names, function(sheet_name) {
  readxl::read_xlsx(path = file, sheet = sheet_name)
})

# use pivot_longer on each sheet to make long data
long_sheet_data <- lapply(sheet_data, function(data) {
  long <- tidyr::pivot_longer(
    data = data,
    cols = !M,
    names_to = "col",
    values_to = "val"
  )
})

# combine into a single tibble
long_data = dplyr::bind_rows(long_sheet_data)

# sum up matching pairs of `M` and `col`
summarised <- long_data %>%
  group_by(M, col) %>%
  dplyr::summarise(agg = sum(val))
  
# convert to a tabular format
tabular <- summarised %>%
  tidyr::pivot_wider(
    names_from = col,
    values_from = agg,
    values_fill = 0
  )

tabular

我使用您的初始输入通过电子表格获得此输出:

> tabular
# A tibble: 7 x 5
# Groups:   M [7]
  M         x     y     z     w
  <chr> <dbl> <dbl> <dbl> <dbl>
1 A         1     2     3     0
2 B         2     3     4     0
3 C         4     6     8     8
4 D         6     8    10     9
5 E         8    10    12    10
6 F         4     5     6    11
7 G         5     6     7    12

【讨论】:

    【解决方案3】:

    您可以使用dplyrtidyr 来获得您想要的结果:

    放手

    df <- data.frame(subject=c(rep("Mother", 2), rep("Child", 2)), modifier=c("chart2", "child", "tech", "unkn"), mother_chart2=1:4, mother_child=5:8, child_tech=9:12, child_unkn=13:16)
    > df
      subject modifier mother_chart2 mother_child child_tech child_unkn
    1  Mother   chart2             1            5          9         13
    2  Mother    child             2            6         10         14
    3   Child     tech             3            7         11         15
    4   Child     unkn             4            8         12         16
    

    df2 <- data.frame(subject=c(rep("Mother", 2), rep("Child", 2)), modifier=c("chart", "child", "tech", "unkn"), mother_chart=101:104, mother_child=105:108, child_tech=109:112, child_unkn=113:116)
    
    > df2
      subject modifier mother_chart mother_child child_tech child_unkn
    1  Mother    chart          101          105        109        113
    2  Mother    child          102          106        110        114
    3   Child     tech          103          107        111        115
    4   Child     unkn          104          108        112        116
    

    然后

    library(dplyr)
    library(tidyr)
    
    df2_tmp <- df2 %>%
      pivot_longer(col=-c("subject", "modifier"))
    
    df %>%
      pivot_longer(col=-c("subject", "modifier")) %>%
      full_join(df2_tmp, by=c("subject", "modifier", "name")) %>%
      mutate(across(starts_with("value"), ~ replace_na(., 0)),
             sum = value.x + value.y) %>%
      select(-value.x, -value.y) %>%
      pivot_wider(names_from=name, values_from=sum, values_fill=0)
    

    返回

    # A tibble: 5 x 7
      subject modifier mother_chart2 mother_child child_tech child_unkn mother_chart
      <chr>   <chr>            <dbl>        <dbl>      <dbl>      <dbl>        <dbl>
    1 Mother  chart2               1            5          9         13            0
    2 Mother  child                2          112        120        128          102
    3 Child   tech                 3          114        122        130          103
    4 Child   unkn                 4          116        124        132          104
    5 Mother  chart                0          105        109        113          101
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    相关资源
    最近更新 更多