1

I am trying to get crosstabs of multiple columns using tidyverse code.

Sample data:

df <- data.frame(col1=c("a", "b", "c", "c"), col2=c(NA, "d", "d","e"))  %>%
  mutate_all(as.character)
df
  col1 col2
1    a <NA>
2    b    d
3    c    d
4    c    e

Using apply, I would do the following:

apply(df, 2, function(x) data.frame(table(x)))

I have tried the code below which does not work:

df %>% 
  map_df(function(.x) {
    group_by(.x) %>% summarise(n=n()) %>% print()
    })
M--
  • 25,431
  • 8
  • 61
  • 93
EML
  • 615
  • 4
  • 14

3 Answers3

2

It can be done using purrr::map like below:

library(purrr)

map(df, ~as.data.frame(table(.x)))

#> $col1
#>   .x Freq
#> 1  a    1
#> 2  b    1
#> 3  c    2
#> 
#> $col2
#>   .x Freq
#> 1  d    2
#> 2  e    1
M--
  • 25,431
  • 8
  • 61
  • 93
1

An option with lapply

lapply(df, function(x) as.data.frame(table(x)))
akrun
  • 874,273
  • 37
  • 540
  • 662
0

In tidyverse you can do this in couple of ways.

  1. column-wise using purrr::map
library(dplyr)
purrr::map(names(df), ~df %>% count(.data[[.x]]))
  1. Get the data in long format and then count for each column and value
df %>%
  tidyr::pivot_longer(cols = everything()) %>%
  count(name, value)
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213