我正在寻找一种快速的方法来在以下格式的列表之间来回:
$`a`
[1] 1 2 3
$`b`
[1] 4 5 6
Run Code Online (Sandbox Code Playgroud)
来自/来自以下格式的data.frame:
name x
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 b 6
Run Code Online (Sandbox Code Playgroud)
(在这种情况下,不要真正关心列的名称是什么.)
这是上面以R格式使用的数据框:
df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6))
Run Code Online (Sandbox Code Playgroud)
同样,我正在寻找两个独立的操作:一个将上面的data.frame转换为一个列表,另一个将它转换回data.frame.
And*_*rie 39
使用stack和unstack在基地R:
x <- data.frame(a=1:3, b=4:6)
x
a b
1 1 4
2 2 5
3 3 6
Run Code Online (Sandbox Code Playgroud)
用于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
Run Code Online (Sandbox Code Playgroud)
用unstack做相反.
unstack(y)
a b
1 1 4
2 2 5
3 3 6
Run Code Online (Sandbox Code Playgroud)
如果您的数据结构比您描述的更复杂,stack并且unstack可能不再合适.在这种情况下,你将不得不使用reshape在基础R,或melt与dcast封装reshape2.
Jac*_*yan 10
我希望提出@Tyler Rinker 的建议,希望这不是微不足道的评论
X <- split(df$x, df$name)
Run Code Online (Sandbox Code Playgroud)
可以更一般地完成
X <- split(df, df$name)
Run Code Online (Sandbox Code Playgroud)
@Tyler Rinker 的split()解释与 R 食谱相匹配
,指定向量可以分组,而实际上整个数据帧都可以分组。我认为对数据框而不是向量进行分组将是更有价值的工具(事实上也是我写这篇文章的原因)。
(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))
Run Code Online (Sandbox Code Playgroud)
HTH。
也许是这样的:
X <- split(df$x, df$name)
data.frame(name = rep(names(X), sapply(X, length)),
x=do.call('c', X))
Run Code Online (Sandbox Code Playgroud)
编辑: 我决定将Andrie和我的解决方案合并为一个看起来正如OP所要求的那样简单的解决方案.话虽如此,我不太了解我会以这种方式处理数据而不是Andrie如何处理数据的情况,因为无论如何数据帧都是等长矢量列表.
# 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
Run Code Online (Sandbox Code Playgroud)
另一种选择是enframe从tibble
library(tidyverse)
enframe(lst1) %>%
unnest
Run Code Online (Sandbox Code Playgroud)
lst1 <- list(a=1:3, b=4:6)
Run Code Online (Sandbox Code Playgroud)