Отменить колонку кадра данных, сохраняя информацию из другого столбца

У меня есть кадр данных, который состоит из двух столбцов: символьный вектор col1 и столбец 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 

Я хочу, чтобы мой col2 все еще сохранял для каждого элемента векторов в списке информацию, хранящуюся в col1 . Чтобы сформулировать это по-разному, в широко используемой терминологии кадрового преобразования данных: колонку «широкий» список следует преобразовать в «длинный» формат.

Тогда в конце дня я хочу два вектора длины, равных length(unlist(myDataFrame$col2)) . В коде:

 # 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 

Я не могу придумать какой-либо простой способ получить его.

Здесь идея состоит в том, чтобы сначала получить длину каждого элемента списка, используя sapply а затем использовать rep для репликации col1 с этой 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" 

Или, как было предложено @ Анандой Махто, вышеизложенное можно также сделать с помощью vapply

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

Вы также можете использовать unnest из пакета 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 

Вы можете использовать «data.table», чтобы развернуть весь data.frame и извлечь интересующий столбец.

 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" 

В новых версиях R теперь можно использовать функцию lengths вместо sapply(list, length) . Функция lengths значительно быстрее.

 with(myDataFrame, rep(col1, lengths(col2))) # [1] "A" "A" "A" "A" "B" "B" "B" "C" "C" "C" "C" "C" "D" "D" 
  • Как сделать сгруппированный макет в igraph?
  • Печать «хороших» таблиц для моделей h2o в R
  • Вставка символа в определенном месте в строке
  • Форматирование реактивных кадров данных в Shiny
  • Подсчитайте количество наблюдений / строк на группу и добавьте результат в кадр данных
  • Как искать материалы «R»?
  • преобразовать кадр данных в json
  • Преобразование данных из длинного формата в широкоформатный с несколькими столбцами измерения
  • Нестандартная оценка (NSE) в dplyr's filter_ и извлечение данных из MySQL
  • более быстрый способ создания переменной, которая агрегирует столбец по id
  • Получение пороговых значений из кривой ROC
  • Давайте будем гением компьютера.