0

I have a dataframe like this:

       date value
 2020-08-10     1
 2020-08-11     1
 2020-08-12     3
 2020-08-13     3
 2020-08-14     5
 2020-08-15     5

And I´m using the table function to create a cross table like this:

table(test$date,test$value)

             1 3 5
  2020-08-10 1 0 0
  2020-08-11 1 0 0
  2020-08-12 0 1 0
  2020-08-13 0 1 0
  2020-08-14 0 0 1
  2020-08-15 0 0 1

But I´d also like to have columns for values 2 and 4 in my table. Is it possible?

Thanks in advance!

2 Answers2

3

I find the easiest way to do this is to convert to a factor with the desired levels:

table(df$date, factor(df$value, levels = 1:5))
#>             
#>              1 2 3 4 5
#>   2020-08-10 1 0 0 0 0
#>   2020-08-11 1 0 0 0 0
#>   2020-08-12 0 0 1 0 0
#>   2020-08-13 0 0 1 0 0
#>   2020-08-14 0 0 0 0 1
#>   2020-08-15 0 0 0 0 1

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
2

We can use model.matrix to create the dummy columns

df1[as.character(1:5)] <- model.matrix(~ factor(value, levels = 1:5) -1, df1)
df1$value <- NULL
df1
#        date 1 2 3 4 5
#1 2020-08-10 1 0 0 0 0
#2 2020-08-11 1 0 0 0 0
#3 2020-08-12 0 0 1 0 0
#4 2020-08-13 0 0 1 0 0
#5 2020-08-14 0 0 0 0 1
#6 2020-08-15 0 0 0 0 1

Or using dcast

library(reshape2)
df1$value <- factor(df1$value, levels = 1:5)
dcast(df1, date ~ value, length, drop = FALSE)

Or with tidyverse

library(dplyr)
library(tidyr)
df1 %>% 
    mutate(n =1) %>%  
    complete(date, value = 1:5, fill = list(n = 0)) %>% 
    pivot_wider(names_from = value, values_from = n)

data

df1 <- structure(list(date = c("2020-08-10", "2020-08-11", "2020-08-12", 
"2020-08-13", "2020-08-14", "2020-08-15"), value = c(1L, 1L, 
3L, 3L, 5L, 5L)), class = "data.frame", row.names = c(NA, -6L
))
akrun
  • 874,273
  • 37
  • 540
  • 662