#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 так, как я думал.
Комментарии:
1. Не могли бы вы уточнить, как должен выглядеть ваш ожидаемый результат? Как вам нужен широкий формат, возможно, вы ищете
bind_cols
?2. Это отличное начало, и оно на самом деле показывает проблему, с которой я сталкиваюсь. Если я использую
bind_cols
свой вывод, он все равно показывает результаты дважды (он повторяет извлеченный кадр данных), и я не понимаю, почему это происходит. Я хочу иметь фрейм данных с двумя столбцами (c(‘foo1’, ‘foo2’)) и столько строк, сколько листов (в данном случае 4 листа, хотя в моем более сложном сценарии есть сотни листов). Я не понимаю, в чем проблема с моим кодом, поэтому буду признателен за любую помощь
Ответ №1:
Все еще не совсем уверен в вашем желаемом результате, но я попробую
- Поскольку вам нужны два столбца
foo1
, иfoo2
я бы предположил, что вы хотите извлечь только первые две строки ваших данных. - Вместо того, чтобы просто получать значения в столбце B ваших листов Excel, извлеките имена и в столбце A, используя
range="A2:B3"
. - Затем используйте bind_rows. Одна из проблем с вашим кодом заключалась в том, что вы дважды передавали список
bind_rows
фреймов данных . - При использовании
bind_rows
добавьте.id
для листов - Помимо переименования, вы можете затем использовать
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). Это не является серьезной проблемой, потому что я могу просто пропустить вторую часть фрейма данных, но я не могу понять, почему это происходит. Но давайте не будем переусердствовать в этом вопросе, вы мне очень помогли.