R中的条件交叉表
Conditional Cross tabulation in R
正在寻找使用 "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
但是,正在寻找一种方法来创建如下所示的 table:
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) 制作一个可以从总和中创建比例的函数。
myprop_tbl <- function(x){
return(round(x*100/sum(x),2))
}
2) 使用 purrr 的地图,将函数应用于您的数据框,然后绑定结果。
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
原始'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 |
正在寻找使用 "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
但是,正在寻找一种方法来创建如下所示的 table:
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) 制作一个可以从总和中创建比例的函数。
myprop_tbl <- function(x){
return(round(x*100/sum(x),2))
}
2) 使用 purrr 的地图,将函数应用于您的数据框,然后绑定结果。
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
原始'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 |