我的数据框包含具有选择多种问题类型的调查的输出。有些单元格有多个值。
df <- data.frame(a=1:3,b=I(list(1,1:2,1:3)))
df
a b
1 1 1
2 2 1, 2
3 3 1, 2, 3
我想将列表弄平以获得以下输出:
df
a b
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
6 3 3
应该很简单但不知何故我无法找到搜索字词。感谢。
答案 0 :(得分:17)
您可以使用&#34; tidyr&#34;:
中的unnest
library(tidyr)
unnest(df, b)
# a b
# 1 1 1
# 2 2 1
# 3 2 2
# 4 3 1
# 5 3 2
# 6 3 3
答案 1 :(得分:7)
使用base R
后,在将'b'列的stack
元素命名为'a'元素后,其中一个选项为list
。我们可以使用setNames
来更改名称。
stack(setNames(df$b, df$a))
或另一种选择是使用unstack
自动将'b'的列表元素命名为'a'元素,然后执行stack
以获得data.frame
输出。< / p>
stack(unstack(df, b~a))
或者,我们可以使用listCol_l
中的便捷功能splitstackshape
将list
转换为data.frame
。
library(splitstackshape)
listCol_l(df, 'b')
答案 2 :(得分:4)
这是一种方式,data.table
:
require(data.table)
data.table(df)[,as.integer(unlist(b)),by=a]
如果b
一致存储,则可以跳过as.integer
。您可以查看
unique(sapply(df$b,class))
# [1] "numeric" "integer"
答案 3 :(得分:3)
这是另一种基本解决方案,远不如迄今为止发布的任何其他解决方案更优雅。为了完整起见,尽管我个人推荐akrun的基础解决方案。
with(df, cbind(a = rep(a, sapply(b, length)), b = do.call(c, b)))
这会将第一列构造为a
的元素,其中每个元素都会重复以匹配b
中相应列表项的长度。使用b
do.call()
时,第二列c()
“展平”。
正如Ananda Mahto在评论中指出的那样,sapply(b, length)
可以在最新版本的R中用lengths(b)
替换(3.2,如果我没有记错的话)。