0

Let me reclaim my question, how I can sum the numbers by row, and list the sum follow by the last column, forming a new column like the second table (sum = a + b+ c + d + e)?

And I also want to know what if some of the values are N/A, can I still treat them as numbers?

Sample input:

     a          b           c          d            e
1    90         67          18         39           74
2    100        103         20         45           50 
3    80         87          23         44           89
4    95         57          48         79           90
5    74         81          61         95           131

Desired output:

     a          b           c          d            e    sum
1    90         67          18         39           74   288
2    100        103         20         45           50   318
3    80         87          23         44           89   323
4    95         57          48         79           90   369
5    74         81          61         95           131  442 
MrFlick
  • 195,160
  • 17
  • 277
  • 295
Bobby
  • 31
  • 1
  • 1
  • 5

3 Answers3

5

To add a row sum, you can use addmargins

M <- matrix(c(90,67,18,39,74), nrow=1)
addmargins(M, 2)   #2 = row margin
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]   90   67   18   39   74  288

If you have missing data, you'll need to change the margin function to something that will properly handle the NA values

M<-matrix(c(90,67,18,NA,74), nrow=1)
addmargins(M, 2, FUN=function(...) sum(..., na.rm=T))
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]   90   67   18   NA   74  249
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • 2
    Or to avoid having to redefine a function - `cbind(M,rowSums(M,na.rm=TRUE))` – thelatemail Apr 15 '15 at 00:18
  • Thanks @MrFilck for your quick anwser. But maybe i didn't state my question clear, I just reclaim my question, could you please help me out again? – Bobby Apr 15 '15 at 00:36
  • What's the problem with my solution? You haven't really made a good [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). What's the class of the object involved? a matrix? a table? a data.frame? `M<-structure(c(90L, 100L, 80L, 95L, 74L, 67L, 103L, 87L, 57L, 81L, 18L, 20L, 23L, 48L, 61L, 39L, 45L, 44L, 79L, 95L, 74L, 50L, 89L, 90L, 131L), .Dim = c(5L, 5L), .Dimnames = list(c("1", "2", "3", "4", "5"), c("a", "b", "c", "d", "e"))); addmargins(M,2)` seems to work just fine. If you have a data.frame, use `addmargins(as.matrix(M),2)` – MrFlick Apr 15 '15 at 00:39
  • That is a matrix. Sorry for the misunderstanding, I am a rookie in R. – Bobby Apr 15 '15 at 00:49
3

Consider using apply(). For example:

set.seed(10) # optional, but this command will replicate data as shown

# create some data
x <-matrix(rnorm(1:25),nrow=5,ncol=5) # 5x5 matrix of random numbers
x
            [,1]       [,2]       [,3]        [,4]       [,5]
[1,]  0.01874617  0.3897943  1.1017795  0.08934727 -0.5963106
[2,] -0.18425254 -1.2080762  0.7557815 -0.95494386 -2.1852868
[3,] -1.37133055 -0.3636760 -0.2382336 -0.19515038 -0.6748659
[4,] -0.59916772 -1.6266727  0.9874447  0.92552126 -2.1190612
[5,]  0.29454513 -0.2564784  0.7413901  0.48297852 -1.2651980

x.sum <-apply(x,1,sum) # sum the rows. Note: apply(x,2,sum) sums cols

x.sum
[1]  1.003356605 -3.776777904 -2.843256446 -2.431935624 -0.002762636

# attach new column (x.sum) to matrix x  
x.sum.1 <-cbind(x,x.sum)

x.sum.1
                                                                    x.sum
[1,]  0.01874617  0.3897943  1.1017795  0.08934727 -0.5963106  1.003356605
[2,] -0.18425254 -1.2080762  0.7557815 -0.95494386 -2.1852868 -3.776777904
[3,] -1.37133055 -0.3636760 -0.2382336 -0.19515038 -0.6748659 -2.843256446
[4,] -0.59916772 -1.6266727  0.9874447  0.92552126 -2.1190612 -2.431935624
[5,]  0.29454513 -0.2564784  0.7413901  0.48297852 -1.2651980 -0.002762636
James Picerno
  • 472
  • 4
  • 16
0

Let's say you have the dataframe df, then you could try something like this:

# Assuming the columns a,b,c,d,e are at indices 1:5
df$sum = rowSums(df[ , c(1:5)], na.rm = T)

Or you could aslo try this:

transform(df, sum=rowSums(df), na.rm = T)
Sandy
  • 1,100
  • 10
  • 18