@GioraSimchoni как это работает?

я есть фрейм данных с категориальной переменной, содержащейсписки строк, с переменной длиной (это важно, потому что в противном случае этот вопрос был бы дубликатомэтот или жеэтот), например:

df <- data.frame(x = 1:5)
df$y <- list("A", c("A", "B"), "C", c("B", "D", "C"), "E")
df
  x       y
1 1       A
2 2    A, B
3 3       C
4 4 B, D, C
5 5       E

И желаемая форма является фиктивной переменной для каждой уникальной строки, видимой в любом местеdf$yт.е.

data.frame(x = 1:5, A = c(1,1,0,0,0), B = c(0,1,0,1,0), C = c(0,0,1,1,0), D = c(0,0,0,1,0), E = c(0,0,0,0,1))
  x A B C D E
1 1 1 0 0 0 0
2 2 1 1 0 0 0
3 3 0 0 1 0 0
4 4 0 1 1 1 0
5 5 0 0 0 0 1

Этот наивный подход работает:

> uniqueStrings <- unique(unlist(df$y))
> n <- ncol(df)
> for (i in 1:length(uniqueStrings)) {
+   df[,  n + i] <- sapply(df$y, function(x) ifelse(uniqueStrings[i] %in% x, 1, 0))
+   colnames(df)[n + i] <- uniqueStrings[i]
+ }

Однако это очень уродливо, лениво и медленно с большими кадрами данных.

Какие-либо предложения? Что-то необычное изtidyverse?

ОБНОВЛЕНИЕ: у меня есть 3 различных подхода ниже. Я проверил их, используяsystem.time на моем (Windows 7, 32 ГБ ОЗУ) ноутбуке нареальный набор данных, состоящий из 1M строк, каждая строка содержит список длиной от 1 до 4 строк (из ~ 350 уникальных значений строк), всего 200 МБ на диске. Таким образом, ожидаемый результат - это фрейм данных с размерами 1M x 350.tidyverse (@Sotos) иbase (@ joel.wilson) подходы заняли так много времени, что мне пришлось перезапустить R.qdapTools (@akrun) подход, однако, работал фантастически:

> system.time(res1 <- mtabulate(varsLists))
   user  system elapsed 
  47.05   10.27  116.82

Так что этот подход я отмечу как принятый.

Ответы на вопрос(3)

Ваш ответ на вопрос