рассчитать сумму строки и произведение в data.frame

r dataframe apply

41535 просмотра

4 ответа

1198 Репутация автора

Я хотел бы добавить к моему data.frame в R столбцы, содержащие суммы строк и продукты. Рассмотрим следующий фрейм данных

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)

но это дает мне вектор строки. Может кто-нибудь показать мне эффективную команду для суммирования и произведения и добавления их к исходному фрейму данных, как показано выше?

Автор: Khurram Majeed Источник Размещён: 24.11.2014 10:49

Ответы (4)


20 плюса

482988 Репутация автора

Решение

Пытаться

 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

Или же

 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

Другой вариант будет использовать rowProdsот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
Автор: akrun Размещён: 24.11.2014 10:51

3 плюса

4380 Репутация автора

Другой подход.

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
Автор: djhurio Размещён: 24.11.2014 10:57

2 плюса

13506 Репутация автора

Также можно выполнить следующее, но необходимо ввести имена столбцов:

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)]
Автор: rnso Размещён: 24.11.2014 11:45

1 плюс

3053 Репутация автора

Только частичный ответ, но если все значения больше или равны 0, rowSums / rowum можно использовать для вычисления продуктов:

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
Автор: r.user.05apr Размещён: 25.07.2018 12:44
Вопросы из категории :
32x32