【问题标题】:bind_rows repeating outputsbind_rows 重复输出
【发布时间】:2021-12-05 12:45:02
【问题描述】:

我正在尝试从 xls 文件中提取数据,这些文件始终具有相同的结构(见下文)。提取感兴趣的范围后:

all_data            <- (file.path(wdir, 'data_input.xlsx'))
excel_sheets(path = all_results)
tab_names           <- excel_sheets(path = all_results)

extracted_data      <- lapply(tab_names, function(x) read_excel(all_data, 
                                                                sheet = x, col_names=FALSE, range = "B2:B4"))

我想把所有东西都变成一个宽格式。然而,当我使用:

extracted_data_wide <- extracted_data %>% bind_rows(extracted_data, .id=NULL)

它似乎重复所有输入一次,这对我来说是不合理的。有没有人可以帮助我了解问题出在哪里,或者谁能为我的问题提供不同的解决方案?我也想过pivot_wider,但它不能像我想象的那样处理输出extracted_data。

示例数据:

【问题讨论】:

  • 您能否澄清一下您的预期结果应该是什么样子?如果您想要宽幅格式,也许您正在寻找bind_cols
  • 这是一个很好的开始,它实际上显示了我面临的问题。如果我使用bind_cols,我的输出仍然会显示两次结果(它重复提取的数据帧),我不明白为什么会发生这种情况。我想要一个包含两列 (c('foo1', 'foo2')) 和与工作表一样多的行的数据框(在这种情况下为 4 个工作表,尽管在我更复杂的情况下有数百个工作表)。我不明白我的代码问题出在哪里,因此感谢您提供任何帮助

标签: dataframe tidyverse


【解决方案1】:

仍然不确定您想要的结果,但我试一试

  1. 由于您需要两列 foo1foo2,我猜您只想提取数据的前两行。
  2. 使用range="A2:B3" 提取A 列中的名称,而不是只获取Excel 工作表B 列中的值。
  3. 之后使用 bind_rows。您的代码的一个问题是您将数据框列表两次传递给bind_rows
  4. 使用bind_rows 时,为工作表添加.id
  5. 除了重命名之外,您还可以使用 pivot_wider 将数据转换为宽格式,其中行对应于工作表,列对应于 Excel 工作表的行
# Make example data
all_results <- tempfile(fileext = ".xlsx")

d1 <- data.frame(
  name = paste0("foo", 1:10),
  value = paste0("bar", 1:10)
)

d2 <- data.frame(
  name = paste0("foo", 1:10),
  value = paste0("bar", 11:20)
)

writexl::write_xlsx(list(d1, d2), path = all_results)

library(readxl)
library(dplyr)
library(tidyr)

tab_names <- excel_sheets(path = all_results)
extracted_data <- lapply(tab_names, function(x) read_excel(all_results, sheet = x, col_names=FALSE, range = "A2:B3"))
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> New names:
#> * `` -> ...1
#> * `` -> ...2

extracted_data_wide <- extracted_data %>% bind_rows(.id = "sheet")

extracted_data_wide %>% 
  rename(foo = 2, value = 3) %>% 
  pivot_wider(names_from = foo, values_from = value)
#> # A tibble: 2 × 3
#>   sheet foo1  foo2 
#>   <chr> <chr> <chr>
#> 1 1     bar1  bar2 
#> 2 2     bar11 bar12

【讨论】:

  • Stefan,这很棒而且非常直观,尤其是在第二部分。非常感谢你!我无法更好地解释问题的第一部分,因为我无法将其置于 MWE 中。当我用我的数据调用 extracted_data_wide &lt;- extracted_data %&gt;% bind_rows(.id = "sheet") 时,我得到的 tibble 的行数是工作表的两倍 (1:n,1:n)。这不是一个主要问题,因为我可以跳过数据帧的第二部分,但我不明白为什么会发生这种情况。但我们现在不要过度设计东西,你帮了我很多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多