当并非所有列中都存在所有值时,如何在R中创建多变量频率表?

当并非所有列中都存在所有值时,如何在R中创建多变量频率表?,r,dataframe,apply,frequency,R,Dataframe,Apply,Frequency,我想在R中制作一个这样的频率表: df = data.frame(aa = c(9,8,7,8), bb = c(9,7,9,8), cc = c(7,9,8,7)) apply(df, 2, table) # outputs: # aa bb cc # 7 1 1 2 # 8 2 1 1 # 9 1 2 1 但是,如果df的其中一列的计数为0(例如,如果我们更改上述值,使df$cc没有9),我们将得到一个列表,而不是一个漂亮的数据帧 # example that

我想在R中制作一个这样的频率表:

df = data.frame(aa = c(9,8,7,8), bb = c(9,7,9,8), cc = c(7,9,8,7))
apply(df, 2, table)

# outputs:  
#   aa bb cc
# 7  1  1  2
# 8  2  1  1
# 9  1  2  1
但是,如果
df
的其中一列的计数为0(例如,如果我们更改上述值,使
df$cc
没有
9
),我们将得到一个列表,而不是一个漂亮的数据帧

# example that gives a list
df = data.frame(aa = c(9,8,7,8), bb = c(9,7,9,8), cc = c(7,8,8,7))
apply(df, 2, table)
有什么简单的方法可以保证数据帧输出,而不考虑计数

我可以想象许多解决方案看起来很混乱或被黑客攻击,例如,这会产生预期的结果:

# example of a messy but correct solution
df = data.frame(aa = c(9,8,7,8), bb = c(9,7,9,8), cc = c(7,8,8,7))
apply(df, 2, function(x) summary(factor(x, levels = unique(unlist(df)))))

有没有更干净的方法呢?

我会继续回答,尽管我仍然反对缺乏标准。如果我们认为“整洁”是“凌乱”的对立面,那么我们应该首先将输入数据整理成长格式。然后我们可以做一个双向

library(tidyr)
df %>% gather %>%
  with(table(value, key))
#      key
# value aa bb cc
#     7  1  1  2
#     8  2  1  2
#     9  1  2  0
感谢Markus提供的基本R版本:

table(stack(df))
#       ind
# values aa bb cc
#      7  1  1  2
#      8  2  1  2
#      9  1  2  0

您发现您找到的解决方案有什么“混乱”之处?我觉得不错。我也可以想出其他的解决方案,但它们是否“混乱”似乎是基于观点的。你能给出一些客观的标准吗?也许是一个使用三个或更少函数的解决方案?我发布的解决方案使用了五种方法。我知道这似乎是武断的,但我认为在某个地方一定有一个函数可以(至少大部分)完成我在这里要做的事情。在baseR
table(stack(df))
Man中,我想我昨天从你那里学到了
stack
,它又派上了用场。伟大的基地R实用功能!从技术上讲,
table(stack(df))
不会返回数据帧,但
as.data.frame.matrix(table(stack(df))
为我完成了这个任务。谢谢。表格不是数据框。您的问题或本答案中的示例都没有给出数据帧,但
as.data.frame.matrix(…)
将为您提供数据帧。