2016-10-02 5 views
0

Я хотел бы спросить, как я могу переписать переменные v и ind в следующей функции:Как передать переменные по ссылке в R?

repcomb <- function(v,n,ind) 
{ 
    k <- length(v) 
    if(ind == 0) 
    { 
     for (i in 1:k) v[i] <- 1 
     ind <- 1 
     return 
    } 
    for (i in k:1) 
    { 
     if(v[i] != n) 
     { 
     for (j in k:i) v[j] <- v[i] + 1 
     return 
     } 
    } 
    ind = 0 
} 

Что это самый простой способ для обновления v и ind?

+0

1) Что вы _really_ пытаетесь сделать? 2) 'i + 1: k' анализирует как' i + (1: k) '; вы, вероятно, имели в виду '(i + 1): k'. –

+0

Спасибо. Это очень простая реализация цикла for. Поскольку единственная реалистическая интерпретация i + 1: k равна (i + 1): k, поэтому я не понимаю, почему она была написана авторами. – TobiR

+0

Вы не ответили на вопрос. Что вы пытаетесь сделать? –

ответ

1

Это самый простой способ:

repcomb <- function(v,n,ind) 
{ 
    k <- length(v) 
    if(ind == 0) 
    { 
    for (i in 1:k) v[i] <- 1 
    ind <- 1 
    return(list(v=v, ind=ind)) 
    } 
    for (i in k:1) 
    { 
    if(v[i] != n) 
    { 
     for (j in i+1:k) v[j] <- v[i] + 1 
     v[i] <- v[i] + 1 
     return(list(v=v, ind=ind)) 
    } 
    } 
    ind = 0 
    return(list(v=v, ind=ind)) 
} 

res <- repcomb(1:5, 4, 2) 
v <- res$v 
ind <- res$ind 
+0

Спасибо! Я что-то неправильно понял? Я реализовал функцию вызова, но есть некоторая ошибка при запуске. Выход функции rep должен содержать векторы «1 1 1», «1 1 2», «1 2 2» и «2 2 2». Rep <- функция() { п <- 2 v <- вектор (режим = "целое число", длина = 3) Ind <- 0 повтор { гр <- repcomb (V, п, иНД) v <- Р.П. $ v Ind <- гр $ Ind если (иНД == 0) перерыв печати (v) }} – TobiR

+0

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

0

Если вы хотите, чтобы вернуть значение параметра, установленного внутри функции, вы можете использовать eval.parent(substitute(val<-new_val)), например:

f_sqr <- function(val){ 
    new_val <- val^2 
    eval.parent(substitute(val<-new_val)) 
} 

Если вы назовите это:

val <- 5 
f_sqr(val) 
val 
#[1] 25 

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

Для собственной функции, это то, что вам нужно сделать для вашего первого if:

repcomb <- function(v, n, ind) 
{ 
    k <- length(v) 
    if (ind == 0) 
    { 
     new_v <- v 
     for (i in 1:k) new_v[i] <- 1 
     # ind <- 1 
     new_ind <- 1 
     eval.parent(substitute(ind<-new_ind)) 
     eval.parent(substitute(v<-new_v)) 
    } 
} 

Тогда, если вы звоните, вы получите изменения обратно:

v <- 1:5 
n <- 3 
ind <- 0 
repcomb(v, n, ind) 
v 
#[1] 1 1 1 1 1 
ind 
#[1] 1 

Соответственно, другая часть может быть изменена в соответствии с тем, что вы хотите.

+0

@TobiR Разве мой ответ не разрешил вашу проблему? – 989

+0

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

+0

@TomasKalibera Это не то, как я его кодировал, это скорее то, что OP, похоже, хочет. – 989

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