2012-03-15 62 views
17

我有一个data.frame,我试图创建一个频率表,显示每行的值的频率。所以我开始是这样的:将数据帧转换为特定格式的频率表

d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 

,看起来像这样:

a b c 
    1 3 1 
    2 4 2 
    3 5 5 

什么我真的想制作的是应急data.frame或矩阵,看起来像这样:

1, 2, 3, 4, 5, 6, 7, 8, 9 
2, 0, 1, 0, 0, 0, 0, 0, 0 
0, 2, 0, 1, 0, 0, 0, 0, 0 
0, 0, 1, 0, 2, 0, 0, 0, 0 

顶行只是一个标签行,不一定在最终结果中。但我在那里添加它来说明。每行显示数字1:9和每个数字在起始数据的每一行中显示的次数。

我无法围绕一个简单的方式来创建这个头。虽然它看起来像table()功能应该是有帮助的,但我无法让它给我任何爱。任何帮助或想法表示赞赏。

+4

你有data.frame全数字的?你多快忘记了,蚱蜢......使用矩阵。 – 2012-03-16 00:46:13

+0

使用矩阵改变答案吗? – 2012-03-16 13:04:08

+0

它不会改变Josh O'Brien的回答,因为'apply'会自动将其第一个参数转换为矩阵/数组。我不确定伊利亚的。无论如何,我大多都在戏弄。 ;-) – 2012-03-16 14:45:20

回答

11

在这里你去:

t(apply(d, 1, tabulate, nbin=9)) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 2 0 1 0 0 0 0 0 0 
[2,] 0 2 0 1 0 0 0 0 0 
[3,] 0 0 1 0 2 0 0 0 0 

(虽然它可能是在这个应用没关系,tabulate()(所使用的代码的内部为table())也是与它进行令人印象深刻的速度不错其计算)


编辑tabulate()没有设置应对0或负整数。如果你想另外一个衬垫,做,你可以使用table()不过,做这样的事情:

d <- data.frame(a=c(0,-1,-2), b=c(3,4,5), c=c(1,2,5)) 

t(apply(d, 1, function(X) table(c(X, -9:9)) - 1)) 
    -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 
[1,] 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 
[2,] 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 
[3,] 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 
+0

绝对(另一个)基地R的简单宝石之一。再次感谢R核心! – 2012-03-15 21:15:12

+0

任何方式使它容纳零和负值?在检查我的用例时,那些比我在做简单问题时意识到的更重要。 – 2012-03-15 21:33:11

+1

@JDLong - 我添加了一个使用'table()'的单行程,可以优雅地处理零和负整数。您只需要调整'-9:9'位以覆盖您感兴趣的范围,并且该范围之外的任何数字仍将包含在表格中。通过添加一些初始行来检查原始data.frame中整数的范围,并在输出表中设置范围,您可以轻松地将其包含到一个很好的小函数中,以执行您想要的操作。干杯。 – 2012-03-15 21:53:40

8

另一种解决方案采用表

library(reshape) 
d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 
d2 <- melt(d) 
d2$rows <- rep(1:nrow(d), ncol(d)) 
table(d2$rows, d2$value) 
+0

这有一个明显的优势,正确处理零和负值,这是我的问题。非常好! – 2012-03-15 21:13:16

相关问题