La columna del dataframe no listada conserva información de otra columna

Tengo un dataframe que consta de dos columnas: un vector de caracteres col1 y una columna de list , col2 .

 myVector <- c("A","B","C","D") myList <- list() myList[[1]] <- c(1, 4, 6, 7) myList[[2]] <- c(2, 7, 3) myList[[3]] <- c(5, 5, 3, 9, 6) myList[[4]] <- c(7, 9) myDataFrame <- data.frame(row = c(1,2,3,4)) myDataFrame$col1 <- myVector myDataFrame$col2 <- myList myDataFrame # row col1 col2 # 1 1 A 1, 4, 6, 7 # 2 2 B 2, 7, 3 # 3 3 C 5, 5, 3, 9, 6 # 4 4 D 7, 9 

Deseo anular la lista de mi col2 manteniendo para cada elemento de los vectores en la lista la información almacenada en col1 . Para expresslo de manera diferente, en terminología de remodelación de dataframe comúnmente utilizada: la columna de lista “amplia” se debe convertir a un formato “largo”.

Entonces, al final del día, quiero dos vectores de longitud igual a la length(unlist(myDataFrame$col2)) . En codigo:

 # unlist myList unlist.col2 <- unlist(myDataFrame$col2) unlist.col2 # [1] 1 4 6 7 2 7 3 5 5 3 9 6 7 9 # unlist myVector to obtain # unlist.col1 <- ??? # unlist.col1 # [1] AAAABBBCCCCCDD 

No puedo pensar en ninguna forma directa de obtenerlo.

Aquí, la idea es primero obtener la longitud de cada elemento de la lista usando sapply y luego usar rep para replicar la col1 con esa length

  l1 < - sapply(myDataFrame$col2, length) unlist.col1 <- rep(myDataFrame$col1, l1) unlist.col1 #[1] "A" "A" "A" "A" "B" "B" "B" "C" "C" "C" "C" "C" "D" "D" 

O como lo sugirió @Ananda Mahto, lo anterior también podría hacerse con vapply

  with(myDataFrame, rep(col1, vapply(col2, length, 1L))) #[1] "A" "A" "A" "A" "B" "B" "B" "C" "C" "C" "C" "C" "D" "D" 

También puede usar unnest del paquete tidyr :

 library(tidyr) unnest(myDataFrame, col2) # row col1 col2 # (dbl) (chr) (dbl) # 1 1 A 1 # 2 1 A 4 # 3 1 A 6 # 4 1 A 7 # 5 2 B 2 # 6 2 B 7 # 7 2 B 3 # 8 3 C 5 # 9 3 C 5 # 10 3 C 3 # 11 3 C 9 # 12 3 C 6 # 13 4 D 7 # 14 4 D 9 

Puede usar “data.table” para expandir todo el data.frame y extraer la columna de interés.

 library(data.table) ## expand the entire data.frame (uncomment to see) # as.data.table(myDataFrame)[, unlist(col2), by = list(row, col1)] ## expand and select the column of interest: as.data.table(myDataFrame)[, unlist(col2), by = list(row, col1)]$col1 # [1] "A" "A" "A" "A" "B" "B" "B" "C" "C" "C" "C" "C" "D" "D" 

En las versiones más nuevas de R, ahora puede usar la función de lengths lugar del sapply(list, length) . La función de lengths es considerablemente más rápida.

 with(myDataFrame, rep(col1, lengths(col2))) # [1] "A" "A" "A" "A" "B" "B" "B" "C" "C" "C" "C" "C" "D" "D"