如何将所有列联表汇总为一个?在 R

问题描述

我在一个 Excel 文件中收集了许多工作表中的许多列联表 (100)。其中一些具有比其他更多的属性。但最后它们都有相同的列名和行名。 (更多属性或更少属性)。 例如,假设我们有这 2 个表。

enter image description here

enter image description here

我想添加属于同一类的每个单元格(第一个表中的行 - Person1 类型 B 和列 B_1 单元格将与第二个表中的行 - Person1 类型 B 和列 B_1 单元格相加,依此类推)

决赛桌将是这样的。请注意 D 不在第一个表中,因此它将按原样存在。

enter image description here

我想将所有列联表汇总(汇集)为一个具有所有可用属性的表。如何在 R 中实现这一点?

谢谢

解决方法

由于您没有提供 excel 文件,我根据您提供的图片制作了一个文件..

看起来像这样
enter image description here enter image description here

library(tidyverse)
library(tidyxl)
library(readxl)
library(data.table)
library(unpivotr)

file_to_read <- "./testdata.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) %>%
    dplyr::select(sheet,row,col,data_type,character,numeric)
  # Cells with the actual data  
  cells_data <-
    dplyr::filter(all_cells,row >= 3,col >= 3) %>%
    dplyr::transmute(row,sheet = sheet,value = numeric)
  # Select the headers
  person.number.up <-
    dplyr::filter(all_cells,row == 1) %>%
    dplyr::select(row,person.number.up = character)
  person.type.up <- 
    dplyr::filter(all_cells,row == 2) %>%
    dplyr::select(row,person.type.up = character)
  person.number.left <-
    dplyr::filter(all_cells,col == 1) %>%
    dplyr::select(row,person.number.left = character)
  person.type.left <- 
    dplyr::filter(all_cells,col == 2) %>%
    dplyr::select(row,person.type.left = character)
  #put together
  final.df <- cells_data %>%
    unpivotr::enhead(person.number.up,"up-ish") %>%
    unpivotr::enhead(person.type.up,"up-ish") %>%
    unpivotr::enhead(person.number.left,"left-ish") %>%
    unpivotr::enhead(person.type.left,"left-ish") %>%
    dplyr::select(-(1:2))
})
# Put together in a data.table
DT <- data.table::rbindlist(L,use.names = TRUE)
# Cast to wide,summing values in the process
ans <- dcast(DT,person.number.left + person.type.left ~ person.number.up + person.type.up,value.var = "value",fun.aggregate = sum,na.rm = TRUE)

enter image description here