Подтвердить что ты не робот

Именованный список в/из 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.

4b9b3361

Ответ 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)