Именованный список в/из Data.Frame
Я ищу быстрый способ вернуться и вперед между списком следующего формата:
$`a`
[1] 1 2 3
$`b`
[1] 4 5 6
в/из файла данных следующего формата:
name x
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 b 6
(На самом деле не важно, какие имена столбцов в этом случае.)
Здесь фрейм данных, используемый выше в R-формате:
df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6))
Опять же, я ищу две отдельные операции: одну для преобразования вышеперечисленного data.frame в список, а другой - для преобразования его обратно в файл data.frame.
Ответы
Ответ 1
Используйте stack
и unstack
в базе R:
x <- data.frame(a=1:3, b=4:6)
x
a b
1 1 4
2 2 5
3 3 6
Используйте stack
от ширины до высокого, т.е. складывайте векторы друг над другом.
y <- stack(x)
y
values ind
1 1 a
2 2 a
3 3 a
4 4 b
5 5 b
6 6 b
Используйте unstack
, чтобы сделать обратное.
unstack(y)
a b
1 1 4
2 2 5
3 3 6
Если ваша структура данных сложнее, чем вы описали, stack
и unstack
больше не подходят. В этом случае вам придется использовать reshape
в базе R или melt
и dcast
в пакете reshape2
.
Ответ 2
Может быть что-то вроде:
X <- split(df$x, df$name)
data.frame(name = rep(names(X), sapply(X, length)),
x=do.call('c', X))
EDIT: Я решил объединить решение Andrie и я в одно, которое, похоже, было именно тем, что OP запросил достаточно просто. Это говорит о том, что я не совсем понимаю ситуацию, когда я буду рассматривать данные таким образом, а не как это сделал Андри, поскольку кадр данных - это список векторов равной длины.
# Your data set
df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6))
# converting it to list of vectors
X <- split(df[, 2], df[, 1])
# converting it to a dataframe
Y <- stack(X)[, 2:1]; names(Y) <- names(df)
# Take Y and feed it back to these lines to show it
# switches back and forth
(X <- split(Y[, 2], Y[, 1]))
Y <- stack(X)[, 2:1]; names(Y) <- names(df);Y
Ответ 3
Я хочу сделать надежно нетривиальное замечание о том, что предложение @Tyler Rinker
X <- split(df$x, df$name)
можно сделать в более общем плане с помощью
X <- split(df, df$name)
Объяснение @Tyler Rinker split() соответствует поваренной книге R
http://my.safaribooksonline.com/book/programming/r/9780596809287/6dot1dot-splitting-a-vector-into-groups/id3392005
указав, что вектор можно сгруппировать, а на самом деле весь блок данных можно сгруппировать. Я бы подумал, что более важным инструментом (и на самом деле тем, что привело меня на этот пост) была бы группировка данных, а не вектора.
(df <- data.frame(name=c(rep("a",3),rep("b",3), rep("c",3)), x=c(1:3,4:6, 7:9)))
(X <- split(df, df$name))
НТН.
Ответ 4
Другой вариант - enframe
из tibble
library(tidyverse)
enframe(lst1) %>%
unnest
data
данные
lst1 <- list(a=1:3, b=4:6)