calculate row sum and product in data.frame

后端 未结 4 1925
一整个雨季
一整个雨季 2020-12-18 23:39

I would like to append a columns to my data.frame in R that contain row sums and products Consider following data frame

x    y     z
1    2     3
2    3             


        
相关标签:
4条回答
  • 2020-12-18 23:50

    Only a partial answer, but if all values are greater than or equal to 0, rowSums/rowsum can be used to calculate products:

    df <- data.frame(x = c(1, 2, 5), y = c(2, 3, 1), z = c(3, 4, 2))
    
    # custom row-product-function
    my_rowprod <- function(x) exp(rowSums(log(x)))
    
    df$prod <- my_rowprod(df)
    df
    

    The generic version is (including negatives):

    my_rowprod_2 <- function(x) {
      sign <- ifelse((rowSums(x < 0) %% 2) == 1, -1, 1)
      prod <- exp(rowSums(log(abs(x)))) * sign
      prod
    }
    df$prod <- my_rowprod_2(df)
    df
    
    0 讨论(0)
  • 2020-12-18 23:53

    Another approach.

    require(data.table)
    
    # Create data
    dt <- data.table(x = c(1,2,5), y = c(2,3,1), z = c(3,4,2))
    
    # Create index
    dt[, i := .I]
    
    # Compute sum and prod
    dt[, sum := sum(x, y, z), by = i]
    dt[, prod := prod(x, y, z), by = i]
    dt
    
    
    # Compute sum and prod using .SD
    dt[, c("sum", "prod") := NULL]
    dt
    dt[, sum := sum(.SD), by = i, .SDcols = c("x", "y", "z")]
    dt[, prod := prod(.SD), by = i, .SDcols = c("x", "y", "z")]
    dt
    
    
    # Compute sum and prod using .SD and list
    dt[, c("sum", "prod") := NULL]
    dt
    dt[, c("sum", "prod") := list(sum(.SD), prod(.SD)), by = i,
       .SDcols = c("x", "y", "z")]
    dt
    
    
    # Compute sum and prod using .SD and lapply
    dt[, c("sum", "prod") := NULL]
    dt
    dt[, c("sum", "prod") := lapply(list(sum, prod), do.call, .SD), by = i,
       .SDcols = c("x", "y", "z")]
    dt
    
    0 讨论(0)
  • 2020-12-19 00:06

    Following can also be done but column names need to be entered:

    ddf$sum = with(ddf, x+y+z)
    ddf$prod = with(ddf, x*y*z)
    ddf
      x y z sum prod
    1 1 2 3   6    6
    2 2 3 4   9   24
    3 5 1 2   8   10
    

    With data.table, another form can be:

    library(data.table)    
    cbind(dt, dt[,list(sum=x+y+z, product=x*y*z),])
       x y z sum product
    1: 1 2 3   6       6
    2: 2 3 4   9      24
    3: 5 1 2   8      10
    

    A simpler version is suggested by @David Arenberg in comments:

    dt[, ":="(sum = x+y+z, product = x*y*z)]
    
    0 讨论(0)
  • 2020-12-19 00:09

    Try

     transform(df, sum=rowSums(df), prod=x*y*z)
     #  x y z sum prod
     #1 1 2 3   6    6
     #2 2 3 4   9   24
     #3 5 1 2   8   10
    

    Or

     transform(df, sum=rowSums(df), prod=Reduce(`*`, df))
     #   x y z sum prod
     #1 1 2 3   6    6
     #2 2 3 4   9   24
     #3 5 1 2   8   10
    

    Another option would be to use rowProds from matrixStats

     library(matrixStats)
     transform(df, sum=rowSums(df), prod=rowProds(as.matrix(df)))
    

    If you are using apply

     df[,c('sum', 'prod')] <-  t(apply(df, 1, FUN=function(x) c(sum(x), prod(x))))
     df
     #  x y z sum prod
     #1 1 2 3   6    6
     #2 2 3 4   9   24
     #3 5 1 2   8   10
    
    0 讨论(0)
提交回复
热议问题