创建显示变量对频率分布的意外事件 table

Create contingency table that displays the frequency distribution of pairs of variables

我想创建一个显示变量对频率分布的意外事件table。这是一个示例数据集:

mm <- matrix(0, 5, 6)
df <- data.frame(apply(mm, c(1,2), function(x) sample(c(0,1),1)))
colnames(df) <- c("Horror", "Thriller", "Comedy", "Romantic", "Sci.fi", "gender")

所有变量都是二进制的,其中 1 表示存在特定电影类型或男性。最后,我想要 table 来计算特定性别下不同电影类型的存在。像这样:

           male female
Horror      1      1
Thriller    1      3
Comedy      2      2
Romantic    0      0
Sci.fi      2      0

我知道我可以为男性和女性分别创建两个 table 不同类型的电影(参见 TarJae 在这里的回答 ),稍后 cbind 它们,但我想在一段代码中完成。如何以高效的方式实现这一目标?

这是使用 dplyrtidyr 的解决方案:

df %>% pivot_longer(cols = -gender, names_to = "type") %>%
  mutate(gender = fct_recode(as.character(gender),Male = "0",Female = "1")) %>% 
  group_by(gender,type) %>% 
  summarise(sum = sum(value)) %>% 
  pivot_wider(names_from = gender,values_from = sum)

给出

# A tibble: 5 x 3
  type      Male Female
  <chr>    <dbl>  <dbl>
1 Comedy       0      1
2 Horror       1      3
3 Romantic     1      1
4 Sci.fi       1      1
5 Thriller     1      1

第二行是可选的,但允许获取变量 gender 的级别。

请在下面找到一个 reprex 和一个使用 data.tablemagrittr(对于管道)的替代解决方案,也在一个块中。

Reprex

  • 您的数据(我为可重复性设置了种子)
set.seed(452)
mm <- matrix(0, 5, 6)
df <- data.frame(apply(mm, c(1,2), function(x) sample(c(0,1),1)))
colnames(df) <- c("Horror", "Thriller", "Comedy", "Romantic", "Sci.fi", "gender")
df
#>   Horror Thriller Comedy Romantic Sci.fi gender
#> 1      0        1      1        0      0      0
#> 2      0        0      0        0      1      0
#> 3      1        0      1        1      0      1
#> 4      0        1      0        0      0      1
#> 5      0        1      0        0      0      1
  • 一个块中的代码
library(data.table)
library(magrittr) # for the pipes!

df %>% 
  transpose(., keep.names = "rn") %>% 
  setDT(.) %>% 
  {.[,  .(rn = rn,
         male = rowSums(.[,.SD, .SDcols = .[, .SD[.N]] == 1]),
         female = rowSums(.[,.SD, .SDcols = .[, .SD[.N]] == 0]))][rn !="gender"]}
  • 输出
#>          rn male female
#> 1:   Horror    1      0
#> 2: Thriller    2      1
#> 3:   Comedy    1      1
#> 4: Romantic    1      0
#> 5:   Sci.fi    0      1

reprex package (v2.0.1)

于 2021-11-25 创建

你可以

sapply(split(df, df$gender), function(x) colSums(x[names(x)!="gender"]))    

#>          0 1
#> Horror   1 1
#> Thriller 1 3
#> Comedy   0 0
#> Romantic 0 0
#> Sci.fi   1 3