r-使用purr::map创建嵌套列联表矩阵

  • 本文关键字:创建 使用 purr map 嵌套 r dplyr
  • 更新时间 :
  • 英文 :


我有一个只包含格式化为因子的分类数据的数据集。我们称之为";mydata";。

我想为mydata中的所有因素组合创建一个数据框架或嵌套列联表的tibble,以便在探索性数据分析中进行审查,并轻松传递给chisq.test((

| na  |   var1   |   var2   |   var3   |  
| var1| tibble   | tibble   | tibble   |  
| var2| tibble   | tibble   | tibble   |  
| var3| tibble   | tibble   | tibble   |  

我已经用dplyr::nest((和purr::map2((尝试了一些不同的尝试。如果可能的话,我更喜欢保持整洁。

下面是我的闭幕式。

mydata <- tibble(var1 = factor(c("a", "b", "c", "c", "b")),
var2 = factor(c("Yes", "No", "Yes", "Yes", "No")),
var3 = factor(c(1, 1, 1, 2, 2))) %>%
pivot_longer(cols = everything(),
names_to = "variable",
values_to = "measure") %>%
nest_by(variable) %>%
mutate(test_map = map2(data, data, table))

我觉得这差不多了,但最终的列联表包括所有因素水平,而不仅仅是相应目标变量的因素水平(例如var1:var1、var1:var2等(

mydata$test_map
$measure

a b c No Yes 1 2
a   1 0 0  0   0 0 0
b   0 2 0  0   0 0 0
c   0 0 2  0   0 0 0
No  0 0 0  0   0 0 0
Yes 0 0 0  0   0 0 0
1   0 0 0  0   0 0 0
2   0 0 0  0   0 0 0
$measure

a b c No Yes 1 2
a   0 0 0  0   0 0 0
b   0 0 0  0   0 0 0
c   0 0 0  0   0 0 0
No  0 0 0  2   0 0 0
Yes 0 0 0  0   3 0 0
1   0 0 0  0   0 0 0
2   0 0 0  0   0 0 0
$measure

a b c No Yes 1 2
a   0 0 0  0   0 0 0
b   0 0 0  0   0 0 0
c   0 0 0  0   0 0 0
No  0 0 0  0   0 0 0
Yes 0 0 0  0   0 0 0
1   0 0 0  0   0 3 0
2   0 0 0  0   0 0 2

这样的东西怎么样:

library(tidyverse)
mydata <- tibble(var1 = factor(c("a", "b", "c", "c", "b")),
var2 = factor(c("Yes", "No", "Yes", "Yes", "No")),
var3 = factor(c(1, 1, 1, 2, 2)))

result <- full_join(tibble(name1 = colnames(mydata), id =1),
tibble(name2 = colnames(mydata), id =1),
by = "id") |>
mutate(tbl = map2(name1, name2, ~table(mydata[[.x]], mydata[[.y]]))) |>
select(-id) |>
pivot_wider(names_from = name2, values_from = tbl)
result
#> # A tibble: 3 x 4
#>   name1 var1            var2            var3           
#>   <chr> <list>          <list>          <list>         
#> 1 var1  <table [3 x 3]> <table [3 x 2]> <table [3 x 2]>
#> 2 var2  <table [2 x 3]> <table [2 x 2]> <table [2 x 2]>
#> 3 var3  <table [2 x 3]> <table [2 x 2]> <table [2 x 2]>
result$var1[1]
#> [[1]]
#>    
#>     a b c
#>   a 1 0 0
#>   b 0 2 0
#>   c 0 0 2

如果您创建了一个由成对的交叉引用变量组成的矩阵,那么您将重复信息。对角线表格也是对角线。

例如:

set.seed(42)
df = data.frame(var1= sample(c("yes","no"),50,T), 
var2 = sample(c("big", "med", "small"), 50, T), 
var3 = colors()[sample(4, 50, T)],
var4 = letters[sample(5,50,T)])
head(df)
#>   var1  var2          var3 var4
#> 1  yes   big         white    e
#> 2  yes   med     aliceblue    a
#> 3  yes   med  antiquewhite    a
#> 4  yes small antiquewhite1    b
#> 5   no small antiquewhite1    b
#> 6   no   big     aliceblue    d

如果不需要对角线和重复的表,可以使用combn为每个组合创建一个列表table函数用于创建corsreference表。

l <- combn(names(df),2, function(x) 
as.data.frame(unclass(table(df[,x]))), simplify = F)
names(l) <- combn(names(df),2, paste, collapse="-", simplify = F)
l
#> $`var1-var2`
#>     big med small
#> no    7  14     6
#> yes  12   7     4
#> 
#> $`var1-var3`
#>     aliceblue antiquewhite antiquewhite1 white
#> no          8            5             7     7
#> yes         4            6             3    10
#> 
#> $`var1-var4`
#>     a b c d e
#> no  6 5 5 8 3
#> yes 4 9 3 4 3
#> 
#> $`var2-var3`
#>       aliceblue antiquewhite antiquewhite1 white
#> big           7            5             2     5
#> med           3            3             6     9
#> small         2            3             2     3
#> 
#> $`var2-var4`
#>       a b c d e
#> big   1 7 4 4 3
#> med   5 4 2 7 3
#> small 4 3 2 1 0
#> 
#> $`var3-var4`
#>               a b c d e
#> aliceblue     5 1 2 3 1
#> antiquewhite  3 2 3 1 2
#> antiquewhite1 0 3 1 6 0
#> white         2 8 2 2 3

然而,如果你想要完整的矩阵,你可以使用applyexpand.grid。下三角中的表格将是相同的,但转置:

l <- apply(expand.grid(names(df),names(df)),1,function(x) 
as.data.frame(unclass(table(df[,x]))), simplify = F)
names(l) <- apply(expand.grid(names(df),names(df)), 1, paste, collapse = "-")
l
l
#> $`var1-var1`
#>     no yes
#> no  27   0
#> yes  0  23
#> 
#> $`var2-var1`
#>       no yes
#> big    7  12
#> med   14   7
#> small  6   4 ......

最后,如果你想要嵌套的tibbles,你可以做:

l <- apply(expand.grid(names(df),names(df)),1,function(x) 
tibble::as.tibble(unclass(table(df[,x]))), simplify = F)
tbl <- tibble::tibble(!!!split(l, rep(1:4,4)))
rownames(tbl)<-names(df)
#> Warning: Setting row names on a tibble is deprecated.
colnames(tbl)<-names(df)
tbl
#> # A tibble: 4 × 4
#>   var1         var2         var3         var4        
#> * <named list> <named list> <named list> <named list>
#> 1 <df [2 × 2]> <df [3 × 2]> <df [4 × 2]> <df [5 × 2]>
#> 2 <df [2 × 3]> <df [3 × 3]> <df [4 × 3]> <df [5 × 3]>
#> 3 <df [2 × 4]> <df [3 × 4]> <df [4 × 4]> <df [5 × 4]>
#> 4 <df [2 × 5]> <df [3 × 5]> <df [4 × 5]> <df [5 × 5]>

但行名称似乎不再被允许。

最新更新