【问题标题】:Calling an assigned variable created within a function in R, within the same function在同一函数中调用在 R 中的函数中创建的分配变量
【发布时间】:2020-03-27 01:09:06
【问题描述】:

我正在编写一个函数来解决数独难题。此函数的一部分将用于将矩阵拆分为三个 9x3 矩阵。然后,在将矩阵重新加入一个大矩阵之前,我将对每个矩阵执行操作。

对于这个阶段,我希望我的这部分功能做三件事:

  1. 将矩阵拆分为三个矩阵
  2. 为每个创建的矩阵命名
  3. 在同一函数中调用新矩阵

但是,我在第 3 步中苦苦挣扎。我编写了一个函数,将矩阵分成三个,命名每个新矩阵,如果我输入envir = globalenv() 行,该函数确实返回我的矩阵分成三个, 9x3 矩阵,每个矩阵都有其单独的标识符名称。太好了!

但是,我希望在函数的下一部分中调用函数的第 1 步和第 2 步创建的新矩阵。在运行函数之前我不会知道矩阵的名称,因为我希望代码可用于许多矩阵,无论大小如何。

有没有办法在 main 函数中调用由 assign 函数创建的对象,而我只知道对象的名称将是“mat_n”,其中 n 是一个整数。

为清楚起见,这是我的代码的简化版本:

m <- matrix(sample(c(0:9), 81, replace = T), ncol = 9, nrow = 9)

matrix_split <- function(x){

  i <- 1:length(x[, 1])
  a <- 1:sum(i %% 3 == 0) # Will be used to name the temporary matrices
  b <- which(i %% 3 == 0) # Will be used to identify where to split main matrix


  for(n in a){  # This is to create a number of smaller matrices depending on the
                # number multiples of 3 that are present in the length of the object.

    nam <- paste("mat_", n, sep = "") # Each new matrix will be named and numbered
                                      # using the assign function below:

    assign(nam, x[, c((b[a[n]] - (sum(i %% 3 == 0) - 1)) : b[a[n]])])

    # Not a very elegant way of using the loop to split the matrix into blocks of
    # three. b[a[n]] returns either 3, 6 or 9, and (sum(i %% == 3) -1 ) = 2. So this
    # will return x[, c(1:3)], x[, c(4:6)] and x[, c(7:9)], when spliting the matrix
    # into three.

    }

}


matrix_split(m)

我只要求调用由 assign 函数创建的对象的特定解决方案,以便在创建后在我的 main 函数中使用。这将是一项有用的技能,并且是我编程知识的空白(根本不是很广泛)。

这可能也不是拆分矩阵的最佳方法,而且我知道已经创建了一些包可以解决数独难题,但我想自己编写,没有比做事更好的学习方法了一开始很糟糕,然后改进它。

【问题讨论】:

    标签: r function assign calling-convention


    【解决方案1】:

    使用lsparent.frame 怎么样?

    mat_4 <- matrix(LETTERS[1:16],nrow=4)
    test <- function(){
    ls(parent.frame())[grep("mat_",ls(parent.frame()))]
    }
    test()
    # [1] "mat_4"
    get(test())
    #      [,1] [,2] [,3] [,4]
    # [1,] "A"  "E"  "I"  "M" 
    # [2,] "B"  "F"  "J"  "N" 
    # [3,] "C"  "G"  "K"  "O" 
    # [4,] "D"  "H"  "L"  "P" 
    

    或者如果你想包含当前环境和更高的每个级别,有sys.frame()

    编辑

    为了避免必须知道对象的名称,也许将结果存储在列表的元素中是一个更好的计划。

    matrix_split <- function(x){
      i <- 1:length(x[, 1])
      a <- 1:sum(i %% 3 == 0) 
      b <- which(i %% 3 == 0)
      #initialize list
      result <- list()
      for(n in a){  
        # assign submatrix to element in the list
        result[[n]] <- x[, c((b[a[n]] - (sum(i %% 3 == 0) - 1)) : b[a[n]])]
        }
    do.call(cbind,result)
    }
    
    matrix_split(m)
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
     [1,]    6    4    2    9    1    2    8    0    4
     [2,]    8    5    5    8    6    1    3    7    8
     [3,]    4    7    1    8    3    6    6    0    6
     [4,]    3    0    5    0    6    3    2    3    9
     [5,]    0    9    7    7    0    1    5    3    2
     [6,]    0    8    8    9    9    8    4    9    8
     [7,]    6    0    2    9    9    2    4    8    9
     [8,]    6    9    6    4    8    1    2    1    1
     [9,]    8    4    6    8    5    0    9    5    9
    

    【讨论】:

    • 您好,我不确定我最后的评论是怎么回事!我再发一次!谢谢您的答复。我会玩弄你提供的功能。我能否在原始函数中使用此函数对每个矩阵进行特定更改?我知道我需要使用 if 语句来实现这一点。
    • 要完全按照自己的意愿去做有点困难。如果您可以将您的请求进一步简化为您缺少的确切功能,我可以试一试。
    • 所以我想在 for 循环中做的是在组合三个矩阵之前更改每个矩阵。我认为最简单的方法是从原始矩阵创建新矩阵,对它们执行一个函数来修改它们,然后用 cbind 将它们绑定在一起。所以 for 循环会将矩阵分成三个,命名并修改它们,在循环之后我将使用 cbind 将它们重新连接在一起。所以我的代码在 for 循环之后会有类似 cbind(mat_n, mat_n2, mat_n3....) 的东西。这更清楚了吗?
    • 我知道您只要求提供特定的解决方案,但请参阅我的编辑以获取使用 assign 的替代解决方案。
    • 太棒了,谢谢!更好的方法。有没有办法在不借助列表的情况下调用和操作在函数中创建的对象,或者如果您正在执行比这段代码更复杂的操作,最好使用列表并使用 if 语句设置规则?
    猜你喜欢
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2015-05-17
    • 1970-01-01
    相关资源
    最近更新 更多