计算data.frame中的行总和和乘积

计算data.frame中的行总和和乘积,r,dataframe,apply,R,Dataframe,Apply,我想在R中的data.frame中附加一列,其中包含行和和和积 考虑下面的数据帧 x y z 1 2 3 2 3 4 5 1 2 我想得到以下信息 x y z sum prod 1 2 3 6 6 2 3 4 9 24 5 1 2 8 10 我试过了 sum = apply(ages,1,add) 但它给了

我想在R中的data.frame中附加一列,其中包含行和和和积 考虑下面的数据帧

x    y     z
1    2     3
2    3     4
5    1     2
我想得到以下信息

x    y     z    sum    prod
1    2     3    6       6  
2    3     4    9       24 
5    1     2    8       10
我试过了

 sum = apply(ages,1,add)
但它给了我一个行向量。有人能告诉我一个有效的求和和和的命令,并将它们附加到原始数据框中,如上图所示吗?

试试看

 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

另一个选项是使用
matrixStats

 library(matrixStats)
 transform(df, sum=rowSums(df), prod=rowProds(as.matrix(df)))
如果您使用的是
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
另一种方法

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
require(data.table)
#创建数据

dt也可以执行以下操作,但需要输入列名:

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
对于data.table,另一种形式可以是:

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
@David Arenberg在评论中建议了一个更简单的版本:

dt[, ":="(sum = x+y+z, product = x*y*z)]

只有部分答案,但如果所有值都大于或等于0,则行和/行和可用于计算乘积:

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

df你能告诉我
Reduce(`*`,df)
有什么作用吗?@Khurram Majeed它类似于
Reduce(
*
,as.list(df))
。由于
data.frame
是一个
列表
,因此不需要使用
As.list
。它将相应位置的每个元素相乘,即第1行、第2行等。您应该演示如何将
lappy
.SD
.SDcols
@Roland一起使用。不要认为
lappy
.SDcols
有必要。在这里,他应该做一些类似
setDT(df)的事情[,”:=“(总和=行总和(.SD),生产=减少(“*”,.SD))]
我用
.SD
添加了解决方案。我看不出
lappy
在这里有什么帮助。@Roland,我添加了
lappy
解决方案。在某些情况下可能有用,但我认为这很难看。为什么我需要在您的第一种方法中创建索引?我想知道您是否可以通过引用而不是使用来分配e> cbind
…类似于
dt[,”:=“(和=x+y+z,积=x*y*z)]
也许吧?我不知道这个更简单的版本。
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
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