1

I have a data frame in the following structure

ChannelId,AuthorId
1,32
28,2393293
2,32
2,32
1,2393293
31,3
3,32
5,4
2,5

What I want is

AuthorId,1,2,3,5,28,31
4,0,0,0,1,0,0
3,0,0,0,0,0,1
5,0,1,0,0,0,0
32,1,2,0,1,0,0
2393293,1,0,0,0,1,0

Is there a way to do this?

Bedi Egilmez
  • 1,494
  • 1
  • 18
  • 26

3 Answers3

5

The xtabs function can be called with a formula that specifies the margins:

 xtabs( ~ AuthorId+ChannelId, data=dat)

         ChannelId
AuthorId  1 2 28 3 31 5
  2393293 1 0  1 0  0 0
  3       0 0  0 0  1 0
  32      1 2  0 1  0 0
  4       0 0  0 0  0 1
  5       0 1  0 0  0 0
IRTFM
  • 258,963
  • 21
  • 364
  • 487
4

Perhaps the simplest way would be: t(table(df)):

#         ChannelId
#AuthorId  1 2 3 5 28 31
#  3       0 0 0 0  0  1
#  4       0 0 0 1  0  0
#  5       0 1 0 0  0  0
#  32      1 2 1 0  0  0
#  2393293 1 0 0 0  1  0

If you want to use dplyr::count you could do:

library(dplyr)
library(tidyr)

df %>%
  count(AuthorId, ChannelId) %>% 
  spread(ChannelId, n, fill = 0)

Which gives:

#Source: local data frame [5 x 7]
#Groups: AuthorId [5]
# 
#  AuthorId     1     2     3     5    28    31
#*    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1        3     0     0     0     0     0     1
#2        4     0     0     0     1     0     0
#3        5     0     1     0     0     0     0
#4       32     1     2     1     0     0     0
#5  2393293     1     0     0     0     1     0
Steven Beaupré
  • 21,343
  • 7
  • 57
  • 77
2

We can also use dcast from data.table. Convert the 'data.frame' to 'data.table' and use dcast with the fun.aggregate as length.

library(data.table)
dcast(setDT(df1), AuthorId~ChannelId, length)
#   AuthorId 1 2 3 5 28 31
#1:        3 0 0 0 0  0  1
#2:        4 0 0 0 1  0  0
#3:        5 0 1 0 0  0  0
#4:       32 1 2 1 0  0  0
#5:  2393293 1 0 0 0  1  0
akrun
  • 874,273
  • 37
  • 540
  • 662