在R中计算多个分类变量的频率

3
我需要创建一个数据框包含先前数据框中每个分类变量的频率。幸运的是,这些变量都结构化为数字形式,从1到5,而非文本。
因此,我可以创建一个新的数据框,第一列包含数字1到5,每个随后的列计算原始数据框中每个变量的该数字作为响应的频率。
例如,我们有一个原始数据框定义为:
df1 <- data.frame(
             Z = c(4,   1,  2,  1,  5,  4,  2,  5,  1,  5),
             Y = c(5,   1,  5,  5,  2,  1,  4,  1,  3,  3),
             X = c(4,   2,  2,  1,  5,  1,  5,  1,  3,  2),
             W = c(2,   1,  4,  2,  3,  2,  4,  2,  1,  2),
             V = c(5,   1,  3,  3,  3,  3,  2,  4,  4,  1))

我需要一个包含以下表格的第二个数据框:

fq  Z   Y   X   W   V
1   3   3   3   2   2
2   4   2   6   10  2
3   0   6   3   3   12
4   8   4   4   8   8
5   15  15  10  0   5

我看到一些使用plyr如何做这样事情的答案,但它们不是系统化的。有人可以帮我吗?

3个回答

6
 table(stack(df1)) * 1:5

    ind
values  Z  Y  X  W  V
     1  3  3  3  2  2
     2  4  2  6 10  2
     3  0  6  3  3 12
     4  8  4  4  8  8
     5 15 15 10  0  5

如果需要一个数据框,可以这样做:
  as.data.frame.matrix(table(stack(df1)) * 1:5)

1
@MartinGal 谢谢。没有看到那个。刚刚检查了第一列。 - Onyambu
我该如何创建一个数据框,而不是普通的表格? - Igor Mendonça
df1堆叠后,使用table()函数生成频率表,再乘以1到5的数字向量,最后将结果转换为数据框。 - Onyambu

4

我们可能会使用

sapply(df1, function(x) tapply(x, factor(x, levels = 1:5),  FUN = sum))
   Z  Y  X  W  V
1  3  3  3  2  2
2  4  2  6 10  2
3 NA  6  3  3 12
4  8  4  4  8  8
5 15 15 10 NA  5

很好!我该如何将那些 NA 改为 0?这个函数内部有方法吗? - Igor Mendonça
1
@IgorMendonça 谢谢。如果out <- sapply(df1, ...); out[is.na(out)] <- 0 - akrun
@IgorMendonça 另外,更紧凑的选项是sapply(df1,\(x) xtabs(x ~ factor(x, levels = 1:5))) - akrun

1

另一个可能的解决方案是基于purrr::map_dfc

library(tidyverse)

map_dfc(df1, ~ 1:5 * table(factor(.x, levels = 1:5)) %>% as.vector) 

#> # A tibble: 5 × 5
#>       Z     Y     X     W     V
#>   <int> <int> <int> <int> <int>
#> 1     3     3     3     2     2
#> 2     4     2     6    10     2
#> 3     0     6     3     3    12
#> 4     8     4     4     8     8
#> 5    15    15    10     0     5

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