将数据框转换为特定格式的频率表

18

我有一个数据框,想要创建一个频率表,显示每行数值的频率。所以我从这里开始:

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
你有一个充满数字的数据框吗?你忘记得太快了,蚂蚱...使用矩阵。 - Joshua Ulrich
使用矩阵会改变答案吗? - JD Long
它不会改变Josh O'Brien的答案,因为apply函数会自动将其第一个参数转换为矩阵/数组。我不确定Ilya的情况。无论如何,我只是开玩笑的。;-) - Joshua Ulrich
我知道你是在开玩笑,但这确实让我想起了一些事情... - JD Long
2个回答

12

Here you go:

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

绝对是 R 基础库中那些简单宝石之一。再次感谢 R 核心开发团队! - Josh O'Brien
有没有办法使其适应零和负值?在检查我的用例时,我意识到它们比我做这个简单问题时想象的更重要。 - JD Long
1
@JDLong -- 我添加了一个使用 table() 的一行代码,可以优雅地处理零和负整数。您只需要调整 -9:9 部分以涵盖您感兴趣的任何范围,超出该范围的任何数字仍将包含在表格中。通过添加几行预处理代码,检查原始数据框中整数的范围并在输出表格中设置范围,您可以轻松地将其封装成一个漂亮的小函数来完成您想要的操作。干杯。 - Josh O'Brien

9

使用表格的另一种解决方案

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)

这具有明显的优势,可以正确处理零和负值,这本来是我接下来要问的问题。非常好! - JD Long

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接