2014-11-12 5 views
0

У меня есть очень большой dataframe ...Множественные применить аргументы с суммой значения функции

v.l.df <- data.frame(seq(0, 10, 0.0001),seq(0, 10, 0.0001),seq(0, 10, 0.0001)) 

... и функции с некоторыми, если отчетность и произведены расчеты ...

a.f <- function(cell_value,action){ 
    if(action == 1){ 
    cell_value * 1 
    } 

    else if(action == 2){ 
    cell_value * 5 
    } 
} 

I теперь хочу применить эту функцию к первым двум столбцам моей строки v.l.df и построить суммы возвратов. Таким образом, новые столбцы должны содержать (псевдокод):

new_col_1         new_col_2 
a.f(v.l.df[1,1],1) + a.f(v.l.df[1,2],1)  a.f(v.l.df[1,1],2) + a.f(v.l.df[1,2],2) 
a.f(v.l.df[2,1],1) + a.f(v.l.df[2,2],1)  a.f(v.l.df[2,1],2) + a.f(v.l.df[2,2],2) 
... 

Как это можно достичь? Я пытаюсь использовать несколько аргументов при использовании apply и сумма возвращаемых значений формирует функцию.

EDIT: Изменена функция примера. Должен ли возвращаться следующий

> a.f(2,1) 
[1] 2 
> a.f(2,2) 
[1] 10 
+0

Что делает ваша функция? Поскольку он закодирован, он ничего не возвращает. Попробуйте запустить 'cell.test = 0.7',' action = 1' и 'a.f (cell.test)', если он вернет 100 или 70? – Bernardo

+0

Извините, я упростил функцию неправильно. Я изменил функцию «a.f» в примере, и теперь она должна работать. – user3347232

+0

- это первый элемент new_col_2, который должен быть 'a.f (v.l.df [1,1], 2) + a.f (v.l.df [1,2], 2) '? – vpipkt

ответ

0

Я сделал бы это в нескольких шагах. Вы можете уменьшить до меньшего числа шагов, но я предпочитаю, чтобы держать его более удобным для чтения:

Во-первых, применять a.f ко всем ячейкам в два раза, используя action=1 и action=2 в первых двух столбцах v.1.df (передать фильме аргументы внутри apply, просто положить их после определения FUN):

action.1 = apply(v.1.df[,1:2], c(1,2), FUN = a.f, action=1) 

action.2 = apply(v.1.df[,1:2] ,c(1,2), FUN = a.f, action=2) 

Тогда ppply rowSums к обоим action.1 и action.2 и сохранять результаты в том же data.frame:

v.l.df$new.1 = rowSums(action.1)   #or v.l.df$new.1 = apply(action.1,1,sum) 
v.l.df$new.2 = rowSums(action.2)   #or v.l.df$new.1 = apply(action.2,1,sum) 
+0

Я получаю эту ошибку при выполнении action.1: 'Ошибка в if (d2 == 0L) {: отсутствует значение, где требуется TRUE/FALSE > traceback() 1: apply (vldf [, 1: 2], c (1, 2), FUN = af, action = 1) ' – user3347232

+0

По-видимому, аргумент' MARGIN' отсутствует. «2» должен сделать трюк. – user3347232

+0

'c (1,2)' - аргумент 'margin', он просто не был явным, тем не менее, у меня не было такой же ошибки с моим кодом, используя ваши данные примера. – Bernardo

0

Я считаю, что ваш результат достигается за счет:

v.l.df$new_col_1 <- a.f(v.l.df$V1, 1) + a.f(v.l.df$V2, 1) 
v.l.df$new_col_2 <- a.f(v.l.df$V1, 2) + a.f(v.l.df$V2, 2) 

Если предположить, что первые две колонки названы V1 и V2 соответственно.

Вы также можете определить другую функцию

a.f.2 <- function(val1, val2, method) { 
    a.f(val1, method) + a.f(val2, method) 
} 

И применять его следующим образом

v.l.df$new_col_1 <- a.f.2(v.l.df$V1, v.l.df$V2, 1) 
v.l.df$new_col_2 <- a.f.2(v.l.df$V1, v.l.df$V2, 2) 

Вы можете написать эту сводную функцию с ... аргументом, чтобы принимать произвольное число входов. Приведенный ниже пример ожидает (и не проверяет) столбцы кадра данных

a.f.n<- function(method,...){ 
    rowSums(sapply(...,a.f,method)) 
} 

Затем примените это следующим образом:

v.l.df$new_col_1 <- a.f.n(v.l.df[,1:1000], method=1) 
v.l.df$new_col_2 <- a.f.n(v.l.df[,1:1000], method=2) 

Я не уверен, насколько эффективно это будет, но она компактна , :-)

+0

Дело в том, что я опубликовал только пример. Реальный 'v.l.df' имеет около 10 000 столбцов (вместо трех), и я хочу использовать это действие для кулака 1000 или около того вместо первых двух. Как ваш ответ может быть адаптирован к этому факту? – user3347232

+0

Один из подходов, как уже упоминалось, заключается в создании второй функции для принятия произвольного числа функций. На данный момент это немного превышает мои знания. Я смотрю на это: http://stackoverflow.com/questions/3057341/how-to-use-rs-ellipsis-feature-when-writing-your-own-function. – vpipkt

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