R: изменить переменные, определенные в функции

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

Например,

 #var1:var10
 foo <- function(){
 var1 = 1
 var2 = 3
 var3 = var1 + var3
 var4 = var3*var2 
 #e.t.c
 return(unlist(as.list(environment())))
 }
 params <- foo()
 foo_solve(model,params)

Есть ли способ получить доступ к переменным, определенным внутри foo, и изменить / перезаписать значения по умолчанию, а затем повторно оценить foo и передать foo_solve?

Я пробовал этот подход:

  foo <- function(..., args = list()) {  
  defaults <- list(a = -1,  c = -3, d = -4)  
  Args <- Reduce(modifyList, list(defaults, args, list(...)))
  return(unlist(Args))
   } 

а как насчет переменных, которые рассчитываются на основе других?

list(a = value, c = value2, d = a + d) не работает.

Заранее спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

К сожалению, вы правильно определили использование функций для своего решения, но полностью перешагнули порог. Но давайте рассмотрим вопросы один за другим:

Is there a way to access the variables defined inside foo?

Нет, по замыслу то, что определено в функции, остается внутри функции и доступно только из функции и ее дочерних элементов (т. Е. Независимо от того, что вызывает сама функция).

Is there a way to ... modify/overwrite the default values?

Это то, для чего нужны аргументы функции, как вы правильно поняли. Но решение проще; во-первых, для входных переменных:

foo <- function(var1 = 1, var2 = 3) {
  var3 <- var1 + var2
  var4 <- var3 * var2
  return(c(var1, var2, var3, var4))
}

Примечание. Ваш оператор return очень трудно читать и потенциально опасен, если вам нужна, скажем, пятая промежуточная переменная. Он тоже будет возвращен, и вы не можете гарантировать порядок возвращаемых переменных.

Если вам нужны именованные переменные, используйте именованный вектор:

  return(c(v1=var1, s2=var2, var3=var3, m4=var4))

Если ваши возвращаемые значения более сложны, чем некоторые скалярные значения, просто используйте list вместо простого c.

but what about the variables that are calculated based on other ones?

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

foo <- function(var1 = 1, var2 = 3, var3, var4) {
  if (missing(var3))
    var3 <- var1 + var2
  if (missing(var4))
    var4 <- var3 * var2
  return(c(var1, var2, var3, var4))
}

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

Но если var3 и var4 — простые вычисления, нельзя ли их просто определить в сигнатуре функции?

  foo <- function(var1 = 1, var2 = 3, var3 = var1 + var2, var4 = var3 * var2) {
    return(c(var1, var2, var3, var4))
  }

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

Другие вопросы по теме