Фон
Я попал в ситуацию, когда один столбец в таблице / кадре данных состоит из списка целочисленных матриц, которые имеют ноль или более строк и ровно 2 столбца. Этот столбец является результатом вызова stringr::str_locate_all()
, поэтому я ожидаю, что это обычный сценарий.
Что я хотел бы сделать, так это выбрать только один из столбцов целочисленных матриц, а затем разложить фрейм данных, но я не понимаю, как это сделать правильно.
Пример
Вот пример (мне нужно создать его вручную, потому что dpasta()
, похоже, не работает с тибблами столбцов списка). В любом случае, моя отправная точка - это вкладка mydf:
library(tidyverse)
m1 <- matrix( c(761,784), nrow=1,ncol=2, dimnames = list(c(),c("start","end")) )
m2 <- matrix( integer(0), nrow=0,ncol=2, dimnames = list(c(),c("start","end")) )
m3 <- matrix( c(1001,2300,1010,2310), nrow=2,ncol=2, dimnames = list(c(),c("start","end")) )
mydf <- tibble( item = c("a","b","c"), pos = list(m1,m2,m3))
Ниже показано, как это выглядит в программе просмотра rstudio. Это вводит в заблуждение, потому что предполагает, что строки pos являются просто векторами целых чисел. На самом деле это матрицы размером nx2, и нет никаких признаков, указывающих на то, что они более сложные. Это вызвало у меня некоторое замешательство, но сейчас не об этом.
Что я хотел бы сделать, так это получить невложенный тиббл, в котором выбран 1-й столбец, начало. Желаемый результат будет выглядеть так (после отмены вложенности):
mydf_desired <- tibble( item = c("a","c","c"), start_pos = c(761,1001,2300))
Обратите внимание, что первая строка в mydf имела только одну строку в матрице pos, поэтому она имеет одну строку в желаемом результате. Строка с item = b имела матрицу 0x2, поэтому она не отображается (но было бы нормально, если бы она также отображалась как NA). Строка с item = c имеет две строки в матрице pos, поэтому она имеет две строки в желаемом результате.
Что я пробовал
Это кажется достаточно простым, у меня раньше были столбцы со списками без вложений. Единственный поворот здесь в том, что мне нужно сначала выбрать начальный столбец, а затем отменить вложение, верно? Я просто map
столбец списка позиций до [, 1], чтобы выбрать 1-й столбец (начальный столбец). И тогда это должно быть вопрос о раскладывании ...
mydf_desired <- mydf %>%
mutate(start_pos = map(pos, ~ .[,1])) %>%
unnest()
#> Error in vec_rbind(!!!x, .ptype = ptype): Internal error in `vec_assign()`: `value` should have been recycled to fit `x`.
#> Warning: `cols` is now required.
#> Please use `cols = c(pos, start_pos)`
Понятия не имею, что на самом деле означает value should have been recycled to fit x
, но это также дает мне предупреждение о том, что нельзя указывать столбцы в unnest()
. Подозрение теперь связано с тем, что я даю unnest()
.
Если я пропущу unnest()
, я не получу эту ошибку ...
mydf_desired <- mydf %>%
mutate(start_pos = map(pos, ~ .[,1]))
И результат выглядит так ...
Это выглядит нормально, я заметил, что для item = b из integer(0)
все еще есть запись pos. Но даже если я пропущу эту строку, я получаю ту же ошибку при попытке unnest()
.
Вот где я в тупике. Почему я не могу просто unnest()
этот кусок? В чем смысл ошибки value should have been recycled to fit x
?