bind_rows повторяющиеся выходы

#dataframe #tidyverse

#фрейм данных #tidyverse

Вопрос:

Я пытаюсь извлечь данные из xls-файлов, которые всегда имеют одну и ту же структуру (см. Ниже). После извлечения интересующих диапазонов с:

 all_data lt;- (file.path(wdir, 'data_input.xlsx')) excel_sheets(path = all_results) tab_names lt;- excel_sheets(path = all_results)  extracted_data lt;- lapply(tab_names, function(x) read_excel(all_data,   sheet = x, col_names=FALSE, range = "B2:B4"))  

Я хотел бы привести все в широкий формат. Тем не менее, когда я использую:

 extracted_data_wide lt;- extracted_data %gt;% bind_rows(extracted_data, .id=NULL)  

кажется, что он повторяет все входные данные один раз, что для меня неправдоподобно. Есть ли кто-нибудь, кто может помочь мне понять, в чем проблема, или кто, возможно, мог бы предложить другое решение моего вопроса? Я тоже думал об pivot_wider этом, но это не работает с выводом extracted_data так, как я думал.

Примеры данных: примерное расположение данных в xls-файле под названием data_input.xlsx

Комментарии:

1. Не могли бы вы уточнить, как должен выглядеть ваш ожидаемый результат? Как вам нужен широкий формат, возможно, вы ищете bind_cols ?

2. Это отличное начало, и оно на самом деле показывает проблему, с которой я сталкиваюсь. Если я использую bind_cols свой вывод, он все равно показывает результаты дважды (он повторяет извлеченный кадр данных), и я не понимаю, почему это происходит. Я хочу иметь фрейм данных с двумя столбцами (c(‘foo1’, ‘foo2’)) и столько строк, сколько листов (в данном случае 4 листа, хотя в моем более сложном сценарии есть сотни листов). Я не понимаю, в чем проблема с моим кодом, поэтому буду признателен за любую помощь

Ответ №1:

Все еще не совсем уверен в вашем желаемом результате, но я попробую

  1. Поскольку вам нужны два столбца foo1 , и foo2 я бы предположил, что вы хотите извлечь только первые две строки ваших данных.
  2. Вместо того, чтобы просто получать значения в столбце B ваших листов Excel, извлеките имена и в столбце A, используя range="A2:B3" .
  3. Затем используйте bind_rows. Одна из проблем с вашим кодом заключалась в том, что вы дважды передавали список bind_rows фреймов данных .
  4. При использовании bind_rows добавьте .id для листов
  5. Помимо переименования, вы можете затем использовать pivot_wider для преобразования ваших данных в широкий формат со строками, соответствующими листам, и столбцами, соответствующими строкам ваших листов Excel
 # Make example data all_results lt;- tempfile(fileext = ".xlsx")  d1 lt;- data.frame(  name = paste0("foo", 1:10),  value = paste0("bar", 1:10) )  d2 lt;- 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 lt;- excel_sheets(path = all_results) extracted_data lt;- lapply(tab_names, function(x) read_excel(all_results, sheet = x, col_names=FALSE, range = "A2:B3")) #gt; New names: #gt; * `` -gt; ...1 #gt; * `` -gt; ...2 #gt; New names: #gt; * `` -gt; ...1 #gt; * `` -gt; ...2  extracted_data_wide lt;- extracted_data %gt;% bind_rows(.id = "sheet")  extracted_data_wide %gt;%   rename(foo = 2, value = 3) %gt;%   pivot_wider(names_from = foo, values_from = value) #gt; # A tibble: 2 × 3 #gt; sheet foo1 foo2  #gt; lt;chrgt; lt;chrgt; lt;chrgt; #gt; 1 1 bar1 bar2  #gt; 2 2 bar11 bar12  

Комментарии:

1. Стефан, это здорово и очень интуитивно понятно, особенно во второй части. Большое спасибо! Я не могу объяснить первую часть вопроса лучше, потому что я не могу сформулировать его в MWE. Когда я звоню extracted_data_wide lt;- extracted_data %gt;% bind_rows(.id = "sheet") со своими данными, я получаю сообщение с вдвое большим количеством строк,чем у меня листов (1:n, 1:n). Это не является серьезной проблемой, потому что я могу просто пропустить вторую часть фрейма данных, но я не могу понять, почему это происходит. Но давайте не будем переусердствовать в этом вопросе, вы мне очень помогли.