2015-11-29 6 views
2

Когда я прошел сценарий стартера R для одного соревнования Kaggle, я увидел, что эта функция создана, чтобы найти сумму всех строк. Вот код:do.call in R - Kaggle стартовый скрипт

#Function to sum across rows for variables defined 
psum <- function(..., na.rm = FALSE) { 
    rowSums(do.call(cbind, list(...)), na.rm = na.rm) 
} 

Может кто-нибудь объяснить, что происходит в этой функции?

Кроме того, как это отличается от использования только rowSums?

+5

Вы посмотрели страницу справки '? Do.call'? Вы видели, какие типы объектов передаются функции 'psum'? – MrFlick

ответ

6

Фактически do.call не требуется. Это может иметь (и должно) было написано более простым способом, как это:

psum2 <- function(..., na.rm = FALSE) rowSums(cbind(...), na.rm = na.rm) 

psum2(BOD, BOD) 
# [1] 18.6 24.6 44.0 40.0 41.2 53.6 

psum(BOD, BOD) # same 
# [1] 18.6 24.6 44.0 40.0 41.2 53.6 

Примечание: В целом мы используем do.call, когда мы не знаем, сколько аргументов будут передано функцию, поэтому мы хотим передать функцию список из них. Следующее:

L <- list(arg1, arg2, arg3) 
do.call(f, L) 

такой же, как:

f(arg1, arg2, arg3) 

, но в первом случае мы можем динамически создавать L таким образом, чтобы он мог иметь любое количество аргументов, в то время как второй случай harded кодируется тремя аргументами ,

Например этот код, который может изменяться путем изменения п (где п может быть 1, 2, 3, ...):

n <- 3 
L <- lapply(1:n, function(i) i * BOD) # create list of n components 

rowSums(do.call(cbind, L)) 
[1] 55.8 73.8 132.0 120.0 123.6 160.8 

против этого кода, который жестко закодированы, чтобы использовать 3 аргумента до cbind:

rowSums(cbind(BOD, 2*BOD, 3*BOD)) # hard coded 
[1] 55.8 73.8 132.0 120.0 123.6 160.8 
+0

Спасибо! Это помогло! – user3252148

3

Он создает функцию под названием psum, которая принимает аргументы «ничего» (...) и na.rm. Это значение передается в do.call, и все, что было передано ..., передается как список. В сущности, do.call будет cbind Все, что находится в ... со всеми ограничениями, которые подходят для cbind. Если какое-то значение будет NA, оно будет удалено. Или нет, в зависимости от значения na.rm.