简体   繁体   English

到/来自 Data.Frame 的命名列表

[英]Named List To/From Data.Frame

I'm looking for a quick way to get back and forth between a list of the following format:我正在寻找一种在以下格式列表之间来回切换的快速方法:

$`a`
  [1] 1 2 3
$`b`
  [1] 4 5 6

to/from a data.frame of the following format:到/来自以下格式的 data.frame:

   name x
 1    a 1
 2    a 2
 3    a 3
 4    b 4
 5    b 5
 6    b 6

(Don't really care what the names of the columns are, in this case.) (在这种情况下,并不真正关心列的名称是什么。)

Here's the data frame used above in R-format:这是上面使用的 R 格式的数据框:

df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6))

Again, I'm looking for two separate operations: one to convert the above data.frame to a list, and another to convert it back to a data.frame.同样,我正在寻找两个单独的操作:一个将上述 data.frame 转换为列表,另一个将其转换回 data.frame。

Use stack and unstack in base R:在基础 R 中使用stackunstack

x <- data.frame(a=1:3, b=4:6)

x
  a b
1 1 4
2 2 5
3 3 6

Use stack to from wide to tall, ie stack the vectors on top of one another.使用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

Use unstack to do the reverse.使用unstack进行相反的操作。

unstack(y)
  a b
1 1 4
2 2 5
3 3 6

If your data structure is more complicated than you described, stack and unstack may no longer be suitable.如果您的数据结构比您描述的更复杂,则stackunstack可能不再适用。 In that case you'll have to use reshape in base R, or melt and dcast in package reshape2 .在这种情况下,你将不得不使用reshape的基础R,或meltdcast封装reshape2

Maybe something like:也许是这样的:

X <- split(df$x, df$name)
data.frame(name = rep(names(X), sapply(X, length)), 
    x=do.call('c', X))

EDIT: I decided to combine Andrie and I's solution into one that appears to be exactly what the OP asked for fairly simple.编辑:我决定将 Andrie 和我的解决方案组合成一个似乎正是 OP 要求的相当简单的解决方案。 That being said I don't quite understand a situation where I would treat the data this way instead of how Andrie did it since a data frame is a list of equal length vectors anyway.话虽如此,我不太明白我会以这种方式处理数据而不是安德里如何处理数据的情况,因为数据帧无论如何都是等长向量的列表。

# 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

Another option is enframe from tibble另一种选择是enframetibble

library(tidyverse)
enframe(lst1) %>%
   unnest

data数据

lst1 <- list(a=1:3, b=4:6)

I wish to make the hopefully non-trivial remark that @Tyler Rinker's suggestion我希望对@Tyler Rinker 的建议发表评论

X <- split(df$x, df$name)

can be done more generally with可以更普遍地完成

X <- split(df, df$name)

@Tyler Rinker's split() explanation matches the R cookbook @Tyler Rinker 的 split() 解释与 R 食谱相符

http://my.safaribooksonline.com/book/programming/r/9780596809287/6dot1dot-splitting-a-vector-into-groups/id3392005 http://my.safaribooksonline.com/book/programming/r/9780596809287/6dot1dot-splitting-a-vector-into-groups/id3392005

specifying that a vector can be grouped, while in fact the entire dataframe can be grouped.指定可以对向量进行分组,而实际上可以对整个数据帧进行分组。 I would think that grouping the dataframe, not the vector, would be the more valuable tool (and in fact what brought me to this post).我认为对数据框而不是向量进行分组将是更有价值的工具(实际上是什么让我看到了这篇文章)。

(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))

HTH.哈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM