在 R 中将 data.frame 变成具有多个级别的 3-way table

Turning a data.frame into a 3-way table with multiple levels in R

我想打开以下内容,手动输入 table,在 R 中输入为 data.frame,代码如下 here:

tab <- data.frame(expand.grid(
  Hair = c("Black", "Brown", "Red", "Blond"),
  Eye = c("Brown", "Blue", "Hazel", "Green"),
  Sex = c("Male", "Female")),
  count = c(32,53,10,3,11,50,10,30,10,25,7,5,3,15,7,8,
            36,66,16,4,9,34,7,64,5,29,7,5,2,14,7,8) ) 

tab

    Hair   Eye    Sex count
1  Black Brown   Male    32
2  Brown Brown   Male    53
3    Red Brown   Male    10
4  Blond Brown   Male     3
...

变成一个table原来的HairEyeColor {datasets}三维数组:

HairEyeColor
, , Sex = Male

       Eye
Hair    Brown Blue Hazel Green
  Black    32   11    10     3
  Brown    53   50    25    15
  Red      10   10     7     7
  Blond     3   30     5     8

, , Sex = Female

       Eye
Hair    Brown Blue Hazel Green
  Black    36    9     5     2
  Brown    66   34    29    14
  Red      16    7     7     7
  Blond     4   64     5     8

我试过 xtabsftable 都没有成功。

由于每个值都在一个唯一的类别中,您可以这样做:

xtabs(count ~ ., data=tab)

如果您希望结果是 data.frames 的列表,请坚持使用 tidyverse 包:

library(tidyverse)
tab %>%
  split(.$Sex) %>%
  purrr::map(tidyr::spread, Eye, count)
#> $Male
#>    Hair  Sex Brown Blue Hazel Green
#> 1 Black Male    32   11    10     3
#> 2 Brown Male    53   50    25    15
#> 3   Red Male    10   10     7     7
#> 4 Blond Male     3   30     5     8
#> 
#> $Female
#>    Hair    Sex Brown Blue Hazel Green
#> 1 Black Female    36    9     5     2
#> 2 Brown Female    66   34    29    14
#> 3   Red Female    16    7     7     7
#> 4 Blond Female     4   64     5     8

一个base R选项是tapply

tapply(tab[,'count'], tab[1:3], FUN = I)

或者我们可以使用dcast

library(data.table)
setDT(tab)[, list(list(dcast(.SD, Hair ~Eye))), Sex]$V1

或者有二维数据可能更好

dcast(setDT(tab), Hair + Sex ~Eye)