根据标签创建数据框分组观察

时间:2013-12-31 14:48:32

标签: r

我有一个x向量,带有分类变量和y数值变量向量,两者长度相同。 我需要创建一个数据框,其中y中的所有数值观察都按x中的分类标签分组,因此最终结果如下所示:

x obs1 obs2 obs3
a 1    3    5
b 6    7    8
c 3    4    6

现在aggregatetapply都需要FUN规范,但我不想对变量进行操作。

x = {从字母表中随机抽样} y = {随机数}

2 个答案:

答案 0 :(得分:2)

请记住,一切都是R中的函数。所以c()之类的东西只是函数调用。

x <- rep(letters[1:3], each=3)
y <- c(1, 3, 5, 6, 7, 8, 3, 4, 6)

foo <- tapply(y, x, c)

# > foo
# $a
# [1] 1 3 5
# $b
# [1] 6 7 8
# $c
# [1] 3 4 6

然后你可以使用这个愚蠢的模式来获取你正在寻找的data.frame:

do.call(rbind, foo)

#   [,1] [,2] [,3]
# a    1    3    5
# b    6    7    8
# c    3    4    6

答案 1 :(得分:0)

我不清楚你的例子中的某些内容:是否有可能x中的每个类别都有不同数量的y值?例如,您会考虑这样的基本数据:

> x <- c(rep(c("a", "b", "c"), 3), "c", "c")
> y <- sample(1:20, 11)
> df <- data.frame(x, y)
> df
   x  y
1  a 16
2  b  4
3  c  9
4  a  2
5  b 12
6  c 17
7  a  7
8  b 10
9  c 11
10 c  1
11 c  8

这里有更多类别c的值。这并不完全是你想要的,但它可能是一个开始:

> library(reshape2)
> dcast(df, x ~ y)
Using y as value column: use value.var to override.
  x  1  2  4  7  8  9 10 11 12 16 17
1 a NA  2 NA  7 NA NA NA NA NA 16 NA
2 b NA NA  4 NA NA NA 10 NA 12 NA NA
3 c  1 NA NA NA  8  9 NA 11 NA NA 17

每个类别的值都显示在右侧行......但是,这些NAs是令人讨厌的。在这种情况下,您希望数据如何显示?像

这样的东西
1 a  2  7 16
2 b  4 10 12
3 c  1  8  9 11 17

当然,这不起作用,因为每一行必须具有相同的列数,因此最后两行中的最后两个元素最终会有NAs。

但是,我怀疑在这种情况下列表可能是最好的解决方案,在这种情况下,考虑一下:

> dl <- split(y, x)
> dl[["a"]]
[1] 16  2  7
> dl$b
[1]  4 12 10
> dl[["c"]]
[1]  9 17 11  1  8

然后,您可以对此列表的元素进行操作。与所有事物R一样,有多种方法可以做到这一点。例如,要将输出作为列表:

> lapply(dl, sum)
$a
[1] 25

$b
[1] 26

$c
[1] 46

或者将输出作为向量

> sapply(dl, sum)
 a  b  c 
25 26 46

或者,或者,将输出作为数据帧:

> library(plyr)
> ldply(dl, sum)
  .id V1
1   a 25
2   b 26
3   c 46

这些机制比rowSum()这样的函数具有更大的通用性,因为你可以将基本的arbirary函数应用于原始列表中的每个元素。