Отменить колонку кадра данных, сохраняя информацию из другого столбца
У меня есть кадр данных, который состоит из двух столбцов: символьный вектор 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))
. В коде:
- Автоматическая упаковка меток с помощью labeller = label_wrap в ggplot2
- Как получить обратную шкалу log10 в ggplot2?
- Подмножество строк, содержащих значения NA (отсутствует) в выбранном столбце кадра данных
- Импорт файлов Excel в R, xlsx или xls
- асимметричное распределение цветов в scale_gradient2?
# 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
Я не могу придумать какой-либо простой способ получить его.
- Программно создавая таблицы Markdown в R с KnitR
- Как реализовать процедуру очистки в R Shiny?
- Как добавить новый столбец в фреймворк данных (на передний план не заканчивается)?
- Частота отсчета в R
- Точка, обрезанная по оси x в ggplot
- Как читать файл csv в R, где некоторые значения содержат символ процента (%)
- Создать счетчик с несколькими переменными
- Как получить среднюю, среднюю и другую статистику по всей матрице, массиву или файлу данных?
Здесь идея состоит в том, чтобы сначала получить длину каждого элемента списка, используя 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"