2014-02-04 4 views
4

Я помогал одному из моих знакомых с его кодом. Я не знал, как объяснить странное поведение, но я мог сказать ему, что его функции явно не возвращают ничего. Вот минимально воспроизводимый пример:Функция R без возвращаемого значения

derp <- function(arg){ 
    arg <- arg+3 
} 

data <- derp(500) 
data 
#[1] 503 
derp(500) 
#nothing outputs 
class(derp(500)) 
#[1] "numeric" 

Есть ли такое имя, которое я могу сделать Google? Почему это происходит? Почему аргумент arg не уничтожается после завершения вызова derp()?

+0

Попробуйте 'г <- Derp (500); z' или '(derp (500)). Также посмотрите, что произойдет, если вы не назначаете 'arg + 3' в источнике своей функции, а затем используете эту функцию. – jbaums

+0

Без 'arg' в конце функции вы ничего не печатаете. Попробуйте '(derp (500))'. – Maiasaura

ответ

6

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

arg <- arg + 3 

(Обратите внимание, что в R, задание является выражением, которое возвращает значение, в данном случае присваивается значение.) Вот почему data <- derp(500) приводит к data, содержащему 503.

Однако возвращаемое значение по умолчанию не выводится на экран, если вы не изолируете окончательное выражение функции в своей собственной строке. Это одна из тех причуд в R. Таким образом, если вы хотите, чтобы увидеть значение:

derp <- function(arg) 
{ 
    arg <- arg + 3 
    arg 
} 

или просто

derp <- function(arg) 
arg + 3 
+4

Я не согласен с вашим утверждением: «Возвращаемое значение не выводится на экран по умолчанию». Он печатается по умолчанию. Проблема в том, что назначение задает видимость для FALSE, чтобы он не отображался. Это та же самая причина, почему, когда вы делаете 'a <- 3', вы также не видите« 3 ». Проверьте 'withVisible (3)' по сравнению с 'withVisible (a <- 3)' – Dason

+1

@Dason или даже 'a <- 3' vs' (a <- 3) ' – hadley

+0

Хорошо, хорошее объяснение. Наверное, это более избыточно, чем странно. Кажется, что это просто цепочки присваивания a <- (b <- 3) – Taylor

1

Переменная arg разрушается. Функция в R будет возвращать значение последнего оператора, выполняемого в функции, если явно не вызывается оператор return.

В вашем случае копия arg является возвращаемым значением вашей функции. Пример:

alwaysReturnSomething = function() 
{ 
    x = runif(1) 
    if(x<0.5) 20 else 10 
} 
> for(x in 1:10) cat(alwaysReturnSomething()) 
20202020102010101020 

или:

alwaysReturnSomething <- function(){} 
> z=alwaysReturnSomething() 
> z 
NULL 
0

Если вы хотите функцию, чтобы изменить значение переменной в глобальной среде вы можно использовать <<- оператора, но вам все еще нужно, чтобы написать точное имя переменной в глобальной среде

derp <- function(arg){ 
    arg <- arg+3 
    b<<-3 
} 

Попробуйте и вызвать b

0

Это любопытное поведение.

В основном derp(), он возвращается, если вы назначаете вывод derp(), а derp() не возвращается, если вы не присвоите результат. Это связано с тем, что функция назначения (<-) возвращается с использованием функции invisible(). см. Make a function return silently, как это работает.

Вы можете увидеть такое же поведение с derp2:

derp2 <- function(arg) { 
    invisible(arg + 3) 
} 
derp2(3) 
# nothing 
b <- derp2(3) 
b 
# 6 
Смежные вопросы