r - R 中的条件交叉表

标签 r dplyr plyr tidyr expss

寻找使用“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)创建一个可以从总和中创建比例的函数。

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

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

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

关于r - R 中的条件交叉表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50055988/

相关文章:

r - 在 dplyr 中,是否可以使用 mutate 指定在何处添加新列?

R编程: Logical test of Previous/preceding/successive Column

R Str_remove 从管道内的多列中删除

r - data.frames 列表到 xts 对象列表

使用 R 中的 plyr 包重命名输出列

r - 如何使用 stat_ellipse 更改 ggplot2 中椭圆的线型?

r - 删除具有多个分组条件的重复项

r - 如何在 mutate_if 中应用 ifelse 语句

swift - 我应该对存储在 Swift 数组中的元素使用类还是结构

R 数据框 - 如何提取唯一值