如何转换' by' [list]输出到数据帧

时间:2014-09-18 22:44:15

标签: r list reshape2 combn

data = data.frame(col1 = c(' m1',' m1',' m1',' m2',& #39; m2',' m2',' m3',' m3'),class = c(' a',& #39; b'' c'' a'' b',' c',' a&# 39;,' b'))我有一个包含2列的data.frame,第1列是模型列表,第2列是模型属性列表。我需要根据他们共享的属性显示模型的组合。我使用' by'得到了组合列表。功能如下:

data= data.frame(col1=c('m1','m1','m1','m2','m2','m3'), class=c('a','b','c','a','b','c'))

data.ls=by(data$col1, data$class,function(x) t(combn(x, 2)))

输出正是我所需要的,但我需要它以data.frame格式而不是列表和'类的名称'出现在每个列表顶部的应列在第三列中:

# data$class: a
# [,1] [,2]
# [1,] m1   m2
# [2,] m1   m3
# [3,] m2   m3
# Levels: m1 m2 m3

所以,我试过这个:

as.data.frame(do.call("rbind",data.ls))

但输出仅显示' col1'的组合。 (使用id值而不是名称)而不是' class'属性,位于' by'中每个列表的顶部。输出。 do.call的输出如下所示:

#   V1 V2
# 1  1  2
# 2  1  2
# 3  1  3

还试过这个:

do.call("rbind.data.frame",data.ls)

得到此错误:NextMethod()中的错误:无效值

决赛桌应如下所示:

data.final= data.frame(col1=c('m1','m1','m1'), col2=c('m2', 'm2', 'm3'), class=c('a','b','c'))

@Richard Scrivens提出以下建议:

newDF <- data.frame(do.call(rbind, lapply(data.ls, as.character)), names(data.ls), row.names = NULL)

输出结果为:

  X1 X2 X3 X4 X5 X6 names.data.ls.
1 m1 m1 m2 m2 m3 m3              a
2 m1 m1 m2 m2 m3 m3              b
3 m1 m2 m1 m2 m1 m2              c

就我而言,这种格式的输出在组合方面不如“&#39; by&#39;列表。

任何帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:0)

您可以使用tapply代替by来避免这种情况。实际上,tapplyby的主力函数。以下结果只需要cbindas.data.frame,但您可以看到这一点。

do.call(rbind, with(data, {
    tapply(as.character(col1), class, function(x) c(combn(x, 2)))
}))
#   [,1] [,2]
# a "m1" "m2"
# b "m1" "m2"
# c "m1" "m3"

同样的结果,您的by电话可以稍微更改一下。

> do.call(rbind, lapply(by(data$col1, data$class, combn, 2), as.character))
#   [,1] [,2]
# a "m1" "m2"
# b "m1" "m2"
# c "m1" "m3"

答案 1 :(得分:0)

'聚合'输出似乎是你想要的:

aggregate(col1~class,data,function(x) t(combn(x, 2)))
  class col1.1 col1.2
1     a     m1     m2
2     b     m1     m2
3     c     m1     m3