Считать столбец списков в кадре данных с колонкой ID

В моем кадре данных содержится вывод опроса с выбранным несколькими типами вопросов. Некоторые ячейки имеют несколько значений.

df <- data.frame(a=1:3,b=I(list(1,1:2,1:3)))
df
  a       b
1 1       1
2 2    1, 2
3 3 1, 2, 3

Я хотел бы сгладить список, чтобы получить следующий вывод:

df
  a       b
1 1       1
2 2       1
3 2       2
4 3       1
5 3       2
6 3       3

должно быть легко, но почему-то я не могу найти условия поиска. спасибо.

Ответы

Ответ 1

Вы можете просто использовать unnest из "tidyr":

library(tidyr)
unnest(df, b)
#   a b
# 1 1 1
# 2 2 1
# 3 2 2
# 4 3 1
# 5 3 2
# 6 3 3

Ответ 2

Используя base R, один параметр stack после наименования элементов list столбца "b" с именем элементов "a". Мы можем использовать setNames для изменения имен.

stack(setNames(df$b, df$a))

Или другим вариантом было бы использовать unstack для автоматического имени элемента списка из 'b' с элементами 'a', а затем сделать stack для получения вывода data.frame.

stack(unstack(df, b~a))

Или мы можем использовать удобную функцию listCol_l из splitstackshape для преобразования list в data.frame.

library(splitstackshape)
listCol_l(df, 'b')

Ответ 3

Здесь один из способов: data.table:

require(data.table)
data.table(df)[,as.integer(unlist(b)),by=a]

Если b сохраняется последовательно, as.integer можно пропустить. Вы можете проверить с помощью

unique(sapply(df$b,class))
# [1] "numeric" "integer"

Ответ 4

Здесь другое базовое решение, гораздо менее элегантное, чем любое другое решение, опубликованное до сих пор. Публикация для полноты, хотя лично я бы рекомендовал базовое решение akrun.

with(df, cbind(a = rep(a, sapply(b, length)), b = do.call(c, b)))

Это создает первый столбец как элементы a, где каждый повторяется, чтобы соответствовать длине соответствующего элемента списка из b. Второй столбец b "сплющен", используя do.call() с c().

Как заметил Ананда Махто в комментарии, sapply(b, length) можно заменить на lengths(b) в самой последней версии R (3.2, если я не ошибаюсь).