0

I have a dataset like the following:

Age      Monday Tuesday Wednesday 
6-9        a     b        a
6-9        b     b        c
6-9              c        a
9-10       c     c        b
9-10       c     a        b

Using R, I want to get the following data set/ results (where each column represents the total frequency of each of the unique factor):

Age        a     b        c
6-9        2     1        0
6-9        0     2        1
6-9        1     0        1
9-10       0     1        2
9-10       1     1        1

Note: My data also contains missing values

user2474226
  • 1,472
  • 1
  • 9
  • 9
fitrat
  • 65
  • 5
  • Hi, I would suggest to produce a [minimal reproducible R example](https://stackoverflow.com/a/5963610/3519756) – Borexino May 12 '20 at 09:58

2 Answers2

1

couple of quick and dirty tidyverse solutions - there should be a way to reduce steps though.

library(tidyverse) # install.packages("tidyverse")

input <- tribble(
~Age, ~Monday, ~Tuesday, ~Wednesday, 
"6-9", "a", "b", "a", 
"6-9", "b", "b", "c", 
"6-9", "", "c", "a",
"9-10", "c", "c", "b", 
"9-10", "c", "a", "b"
)

# pivot solution
input %>% 
  rowid_to_column() %>% 
  mutate_all(function(x) na_if(x, "")) %>%
  pivot_longer(cols = -c(rowid, Age), values_drop_na = TRUE) %>% 
  count(rowid, Age, value) %>% 
  pivot_wider(id_cols = c(rowid, Age), names_from = value, values_from = n, values_fill = list(n = 0)) %>% 
  select(-rowid)

# manual solution (if only a, b, c are expected as options)
input %>% 
  unite(col = "combine", Monday, Tuesday, Wednesday, sep = "") %>% 
  transmute(
    Age,
    a = str_count(combine, "a"),
    b = str_count(combine, "b"),
    c = str_count(combine, "c")
  )
CourtesyBus
  • 331
  • 2
  • 4
0

In base R, we can replace empty values with NA, get unique values in the dataframe, and use apply row-wise and count the occurrence of values using table.

df[df == ''] <- NA
vals <- unique(na.omit(unlist(df[-1])))
cbind(df[1], t(apply(df, 1, function(x) table(factor(x, levels = vals)))))


#   Age a b c
#1  6-9 2 1 0
#2  6-9 0 2 1
#3  6-9 1 0 1
#4 9-10 0 1 2
#5 9-10 1 1 1
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213