R中的条件交叉表

Posted

技术标签:

【中文标题】R中的条件交叉表【英文标题】:Conditional Cross tabulation in R 【发布时间】:2018-10-07 22:05:47 【问题描述】:

寻找使用“expss”包完成以下任务的最快方法。

有了一个很棒的“expss”包,我们可以很容易地做交叉制表(交叉制表的其他优点和有用的功能。),我们可以很容易地交叉制表多个变量,如下所示。

 #install.packages("expss")

 library("expss")
 data(mtcars)


  var1 <- "vs, am, gear, carb"
  var_names = trimws(unlist(strsplit(var1, split = ","))) 


  mtcars %>%
    tab_prepend_values %>%
    tab_cols(total(), ..[(var_names)]) %>%
    tab_cells(cyl) %>%
    tab_stat_cpct() %>%
    tab_pivot()

以上给出的输出为:(列 %)

                      #Total    vs          am          gear            carb                        
                                0     1     0     1     3     4   5     1   2    3   4    6    8 

  cyl             4    34.4   5.6  71.4  15.8  61.5   6.7  66.7  40  71.4  60                    
                  6    21.9  16.7  28.6  21.1  23.1  13.3  33.3  20  28.6           40  100      
                  8    43.8  77.8        63.2  15.4  80.0        40        40  100  60       100 
       #Total cases    32.0  18.0  14.0  19.0  13.0  15.0  12.0   5   7.0  10    3  10    1    1 

但是,正在寻找一种方法来创建如下表:

 CYL    |  VS = 0   |  AM = 1   |   Gear = 4 or Gear = 5    |  Carb (All)
   4        5.56        61.54               58.82                34.38
   6        16.67       23.08               29.41                21.88
   8        77.78       15.38               11.76                43.75

Total(col%) 100.00      100.00              100.00               100.00

虽然我可以使用 dplyr 和 join 函数来实现这一点,但这太复杂了,因为我们必须在运行时或动态地传递变量。

任何帮助都将是可观的。谢谢!!

【问题讨论】:

【参考方案1】:

你可以试试这个:

1) 制作一个可以从总和中创建比例的函数。

myprop_tbl <- function(x)
    return(round(x*100/sum(x),2))

2) 使用 purrr 的 map,将函数应用到数据框上,然后绑定结果。

library(tidyverse)
tab <- mtcars %>% 
    group_by(cyl) %>% 
    summarise(vs_sum = sum(vs==0), am_sum = sum(am==1), 
              gear_sum = sum(gear == 4|gear==5), carb_sum= n())

finaltab <- bind_cols(tab[,1],map_df(tab[,2:length(tab)], myprop_tbl))

输出

# * cyl vs_sum am_sum gear_sum carb_sum
#  <dbl>  <dbl>  <dbl>    <dbl>    <dbl>
#1  4.00   5.56   61.5     58.8     34.4
#2  6.00  16.7    23.1     29.4     21.9
#3  8.00  77.8    15.4     11.8     43.8**

编辑:

和OP商量了一下,好像他也想传一串函数,

我在这里使用一个包seplyr

tab <- mtcars %>% 
    group_by(cyl) %>% 
    summarise_se(c("vs_sum = sum(vs==0)",
              "am_sum = sum(am==1)",
              "gear_sum = sum(gear == 4|gear==5)", 
              "carb_sum = n()"))

它也有效,但你会得到奇怪的名字,要解决这个问题,你可以这样做:

这完全可以作为我发布的原始答案:

tab <- mtcars %>% 
    group_by(cyl) %>% 
    summarise_se(c("vs_sum" := "sum(vs==0)",
              "am_sum" := "sum(am==1)",
              "gear_sum" := "sum(gear == 4|gear==5)", 
              "carb_sum" := "n()"))

你可以在这里阅读这个@这个link

【讨论】:

我真的很喜欢你使用 tidyverse 实现这一目标的方式,有什么方法可以传递“summarise(vs_sum = sum(vs==0), am_sum = sum(am==1) , gear_sum = sum(gear == 4|gear==5), carb_sum= n())" 作为汇总函数中的字符串? @ayush,我们可以传递带引号的变量,但从未见过传递函数字符串,我确信这是可以实现的,但我也不知道。 是的,我明白...非常感谢...如果您以后发现相同的内容,如果您能分享相同的内容,将不胜感激...祝您有美好的一天! 可以实现如下的单个变量信息: D_string % group_by(cyl) %>% summarise_(​​D_string) 然而对于多个变量,它会产生问题...D_string @ayush,谢谢!!!对于多个语句,如果您使用evalparse,您可以实现这一点,tab &lt;- mtcars %&gt;% group_by(cyl) %&gt;% summarise(eval(parse(text="vs_sum = sum(vs==0)")), eval(parse(text="am_sum = sum(am==1)"))),但如果找到管道(|)或函数等字符时会失败【参考方案2】:

使用原始“tab_*”的解决方案:

library("expss")
data(mtcars)
var_text = "vs_sum = vs==0, am_sum = am==1, gear_sum = gear == 4|gear==5, carb_sum = total(carb)"
var_expr = parse(text = sprintf("data.frame(%s)", var_text)) # parse text string to expression

var_list = calc(mtcars, 1*eval(var_expr)) %>% # caclulate data.frame with zero/one columns
    prepend_names() %>% # add names as labels
    mis_val(0) %>% # we don't need columns with FALSE condition
    set_val_lab(c("|" = 1)) # suppress values in table - we don't want to see TRUE/1

mtcars %>%
    tab_prepend_values %>%
    tab_cols(total(), var_list) %>%
    tab_cells(cyl) %>%
    tab_stat_cpct() %>%
    tab_pivot()

 # |     |              | #Total | vs_sum | am_sum | gear_sum | carb_sum  |
 # | --- | ------------ | ------ | ------ | ------ | -------- | --------- |
 # | cyl |            4 |   34.4 |    5.6 |   61.5 |     58.8 |      34.4 |
 # |     |            6 |   21.9 |   16.7 |   23.1 |     29.4 |      21.9 |
 # |     |            8 |   43.8 |   77.8 |   15.4 |     11.8 |      43.8 |
 # |     | #Total cases |   32.0 |   18.0 |   13.0 |     17.0 |      32.0 |

【讨论】:

嗨@gregory Demin,在从shiny 下载文件时,我们正在获取列标题以th text-align: center; 开头的表格。 th border: 1px solid #DDD ,你能帮忙

以上是关于R中的条件交叉表的主要内容,如果未能解决你的问题,请参考以下文章

解释 MySQL 外连接内连接与自连接的区别?

oracle连接总结(内连接外连接自然连接,交叉连接,自连接)

解析:内联,左外联,右外联,全连接,交叉连接的区别

如何编写 R 函数来查找数据框中的特定条件

SQL的连接分为三种:内连接外连接交叉连接

了解Mysql