2014-11-24 2 views
6

Я хотел бы, чтобы присоединять колонки к моему data.frame в 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) 

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

ответ

13

Попробуйте

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 

Другим вариантом было бы использовать rowProdsmatrixStats из

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 
+0

Может у ou, пожалуйста, сообщите мне, что '' 'Уменьшить (' * ', df)' '' делает? –

+0

@ Khurram Majeed Это похоже на 'Reduce (' * ', as.list (df))'. Поскольку 'data.frame' является' list', вам не нужно использовать 'as.list'. он умножает каждый элемент на позиции коррекции, то есть 1-я строка, 2-я строка и т. д. – akrun

3

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

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

Вы должны продемонстрировать, как использовать 'lapply' в сочетании с' .SD' и '.SDcols'. – Roland

+1

@Roland, не думайте, что здесь есть необходимость в 'lapply' или' .SDcols', он должен был просто сделать что-то вроде 'setDT (df) [,": = "(sum = rowSums (.SD), prod = Reduce ("*", .SD))] ' –

+0

Я добавил решение с' .SD'. Я не вижу, как здесь может помочь «lapply». – djhurio

1

После также может быть сделано, но имена столбцов должны быть введены:

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

Интересно, можно ли просто назначить по ссылке вместо использования 'cbind' ... Что-то вроде' dt [, ": =" (sum = x + y + z, product = x * y * z)] 'может быть? –

+0

Я не знал об этой более простой версии. – rnso

Смежные вопросы