0

我正在尝试构建一个可以接受公式列表作为参数的函数。

我首先定义将作为参数输入到函数中的变量。前两个变量被命名为包含布尔信息的向量。

named_variable_vector <- c(0, 1, 1)
names(named_variable_vector) <- c("M", "E", "L")
named_variable_vector

named_parameter_vector <- c(0, 0)
names(named_parameter_vector) <- c("G_e", "L_e")
named_parameter_vector

第三个参数是公式对象的列表。公式是一个“语言”类对象,除非使用f_eval()函数明确告知这样做,否则它不会被评估。

logic_list <- list(~((G_e + 1)*(L + L_e + L*L_e))%%2, ~M , ~((G_e + 1)*E*L_e)%%2)

好的,是时候构建函数了。第一步是在函数中创建局部变量。这些局部变量将以 named_vector 参数的名称命名。

Boolean_state_space <- function(variables, parameters, logic) {

  variable_names <- names(variables)
  parameter_names <- names(parameters)

  ####generate local variables

  #assign variable values to variable names
  for (i in 1:length(variables)) {
    assign(variable_names[i], variables[i])

  }
  #assign parameter values to parameter names
  for (j in 1:length(parameters)) {
    assign(parameter_names[j], parameters[j])
  }

然后我初始化一个矩阵。之后,我打印出局部变量来测试它们是否成功。这只是一条测试线,不会出现在函数的最终版本中。

#initialize matrix
  state_space_matrix <- matrix(nrow = 4, ncol = length(c(variable_names, parameter_names)))
  colnames(state_space_matrix) <- c(variable_names, parameter_names)
  rownames(state_space_matrix) <- c(1:nrow(state_space_matrix))
  row.names(state_space_matrix)[1] <- c("t")


  state_space_matrix[1,] <- c(variables, parameters)
  state_space_matrix[,c(ncol(state_space_matrix) - 1, ncol(state_space_matrix) )] <-parameters
  print(state_space_matrix) #test to see if matrix was initialized succesfully
  print(c(M, E, L, G_e, L_e)) #test to see if local variables were successfully defined within the function

最后,是时候使用逻辑论证了!这里的目标是让函数使用逻辑参数中提供的方程,通过使用前一行中可用的值来“更新”矩阵的下一行。

第一行按顺序计算方程,然后将这些值分配给矩阵中的下一行。这是发生错误的地方。

  for (k in 2:nrow(state_space_matrix)) {

    for (h in 1:length(variable_names)) {
      state_space_matrix[k, variable_names[h]] <- f_eval(logic[[h]])
      print("test")

    }

第二行现在使用矩阵最近更新的行中的值重新分配变量的值。

for (g in 1:length(variable_names)) {
      assign(variable_names[g], state_space_matrix[k, g])
    } 
  }
  print(state_space_matrix)  
}  #end of function

好的,当我使用开始时设置的参数运行函数时:

Boolean_state_space(named_variable_vector, named_parameter_vector, logic_list)

我收到以下错误:

Error in eval(expr, data, expr_env) : object 'G_e' not found 

我无法为我的生活找出原因。为什么函数看不到我之前定义的局部变量?这些变量需要用于评估公式。

PS我相信可能有更好/更优雅的方式来使用类似的参数格式编写这个函数,我很想知道它们。但是出于学习的目的,我真的很想知道我编写这个函数的方法是否可行。

PPS 当我单独运行函数的内部时(在全局环境中也称为),我的方法效果很好。结果如下所示:在此处输入图像描述

4

1 回答 1

1

带参数列表的解决方案

我通过使用参数列表而不是依赖正确的环境来明确数据来解决这个问题。

Boolean_state_space <- function(variables, parameters, logic) {

    variable_names <- names(variables)
    parameter_names <- names(parameters)

####generate local variables

                                        #assign variable values to variable names
    for (i in 1:length(variables)) {
        assign(variable_names[i], variables[i])

    }
    print(variable_names)
                                        #assign parameter values to parameter names
    for (j in 1:length(parameters)) {
        assign(parameter_names[j], parameters[j])
    }


                             #initialize matrix
    state_space_matrix <- matrix(nrow = 4, ncol = length(c(variable_names, parameter_names)))
    colnames(state_space_matrix) <- c(variable_names, parameter_names)
    rownames(state_space_matrix) <- c(1:nrow(state_space_matrix))
    row.names(state_space_matrix)[1] <- c("t")


    state_space_matrix[1,] <- c(variables, parameters)
    state_space_matrix[,c(ncol(state_space_matrix) - 1, ncol(state_space_matrix) )] <-parameters
    print(state_space_matrix) #test to see if matrix was initialized succesfully
    print(c(M, E, L, G_e, L_e)) #test to see if local variables were successfully defined within the function

## CREATE PARAMETER LIST

    param_list <- split(unname(parameters), names(parameters))
    param_list <- c(split(unname(variables), names(variables)), param_list)
    cols <- names(variables)
    for (k in 2:nrow(state_space_matrix)) {

        for (h in 1:length(variable_names)) {
            state_space_matrix[k, cols[h]] <- lazyeval::f_eval(logic[[h]], param_list)
            print("test")

        }
## UPDATE PARAMETER LIST WITH CURRENT VALUES 
        for (g in 1:length(variable_names)) {
            param_list[variable_names[g]] <- state_space_matrix[k, g]
        }
    }
    print(state_space_matrix)
}

Boolean_state_space(named_variable_vector, named_parameter_vector, logic_list)

使用环境的替代解决方案

Boolean_state_space <- function(variables, parameters, logic) {

    variable_names <- names(variables)
    parameter_names <- names(parameters)

####generate local variables

                                        #assign variable values to variable names
    for (i in 1:length(variables)) {
        assign(variable_names[i], variables[i])

    }
                                        #assign parameter values to parameter names
    for (j in 1:length(parameters)) {
        assign(parameter_names[j], parameters[j])
    }

    state_space_matrix <- matrix(nrow = 4, ncol = length(c(variable_names, parameter_names)))
    colnames(state_space_matrix) <- c(variable_names, parameter_names)
    rownames(state_space_matrix) <- c(1:nrow(state_space_matrix))
    row.names(state_space_matrix)[1] <- c("t")


    state_space_matrix[1,] <- c(variables, parameters)
    state_space_matrix[,c(ncol(state_space_matrix) - 1, ncol(state_space_matrix) )] <-parameters
    print(state_space_matrix) #test to see if matrix was initialized succesfully
    print(c(M, E, L, G_e, L_e)) #test to see if local variables were successfully defined within the function
    print(parent.frame())
# Get correct environment
    env <- pryr::where(variable_names[1])
    for (k in 2:nrow(state_space_matrix)) {

        for (h in 1:length(variable_names)) {
# Set environment to evaluate functions in 
            rlang::f_env(logic[[h]]) <- env
            state_space_matrix[k, variable_names[h]] <- lazyeval::f_eval(logic[[h]])
            print("test")

        }

        for (g in 1:length(variable_names)) {
            assign(variable_names[g], state_space_matrix[k, g])
        } 
    }
    print(state_space_matrix)  
}

Boolean_state_space(named_variable_vector, named_parameter_vector, logic_list)
于 2019-08-24T20:51:47.110 回答