3

I have a simple R problem, but I just can't find the answer. I have a dataframe like this:

A    1    0    0    0    0    0
B    0    1    0    0    0    0
B    0    0    1    0    0    1
B    0    0    0    0    1    0
C    1    0    0    0    0    0
C    0    0    0    1    1    0

And i want it to be just like this:

A    1    0    0    0    0    0
B    0    1    1    0    1    1
C    1    0    0    1    1    0

Thank you very much!

Regards Lisanne

Lisann
  • 5,705
  • 14
  • 41
  • 50

3 Answers3

4

Here's one possbility using tapply:

cbind(unique(dat[1]), do.call(rbind, tapply(dat[-1], dat[[1]], colSums)))

#   V1 V2 V3 V4 V5 V6 V7
# 1  A  1  0  0  0  0  0
# 2  B  0  1  1  0  1  1
# 5  C  1  0  0  1  1  0

where dat is the name of your data frame.

Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
4
dat <- structure(list(V1 = structure(c(1L, 2L, 2L, 2L, 3L, 3L), .Label = c("A", 
"B", "C"), class = "factor"), V2 = c(1L, 0L, 0L, 0L, 1L, 0L), 
    V3 = c(0L, 1L, 0L, 0L, 0L, 0L), V4 = c(0L, 0L, 1L, 0L, 0L, 
    0L), V5 = c(0L, 0L, 0L, 0L, 0L, 1L), V6 = c(0L, 0L, 0L, 1L, 
    0L, 1L), V7 = c(0L, 0L, 1L, 0L, 0L, 0L)), .Names = c("V1", 
"V2", "V3", "V4", "V5", "V6", "V7"), class = "data.frame", row.names = c(NA, 
-6L))

You could...

aggregate(.~ V1 , data =dat, sum)

or

library(plyr)
ddply(dat, .(V1), function(x) colSums(x[,2:7])  )

If you're working with a data.frame where there are duplicates but you only want the presence or absence of a 1 to be noted, then after these functions you might want to do something like dat[!(dat %in% c(1,0)] <- 1.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
user1317221_G
  • 15,087
  • 3
  • 52
  • 78
1

A possibility not mentioned is the aggregate function. I think this is quite 'readable'.

aggregate(cbind(data$X1, data$X2, data$X3, data$X4), 
by = list(category = data$group), FUN = sum)
Simon
  • 143
  • 10