使用ID列展平数据框中的列表列

时间:2015-05-14 17:24:18

标签: r dataframe reshape

我的数据框包含具有选择多种问题类型的调查的输出。有些单元格有多个值。

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

应该很简单但不知何故我无法找到搜索字词。感谢。

4 个答案:

答案 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中的便捷功能splitstackshapelist转换为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,如果我没有记错的话)。

相关问题