累积对列表元素的更改

时间:2018-11-29 08:41:42

标签: r tidyverse purrr

我一直在构建一个程序包,该程序包允许用户导入Excel文件,并根据其中的列对不同的工作表进行更改。我已经通过利用R的作用域规则来实现这一点。下面是一个非常简化且可复制的示例:

require(tidyverse)

df <- data.frame(count = 1:3, 
                 number = 4:2)

commands <- data.frame(command = c("a", "a", "b"),
                      column = c("count", "count", "number"),
                      stringsAsFactors = F)

combo <- list(df = df, commands = commands)

commander <- function(x) {
   command_a <- function(column) {
      x$df <<- dplyr::mutate(x$df, !!column := !!sym(column) + 1)
   }

   command_b <- function(column) {
      x$df <<- dplyr::mutate(x$df, !!column := !!sym(column) - 1)
   }

   general_command <- function(comm, col) {
      if(comm == "a") {
         command_a(col)
      }
      else if (comm == "b") {
         command_b(col)
      }
   }

   purrr::pmap(list(x$commands$command,
                    x$commands$column),
               general_command)

   return(x)
}

commander(combo)

这可行,但是现在我希望能够清除该列表的不同元素(Excel中的表格)。因此,出于对代码更具可读性/更好的渴望,我想将command_acommand_b移到全局位置。但是,我正在努力更改传递给commander函数的实际列表对象。

require(tidyverse)

df <- data.frame(count = 1:3, 
                 number = 4:2)

commands <- data.frame(command = c("a", "a", "b"),
                       df = c("df", "df", "df"),
                      column = c("count", "count", "number"),
                      stringsAsFactors = F)

combo <- list(df = df, commands = commands)

command_a <- function(df, column) {
   df <- dplyr::mutate(df, !!column := !!sym(column) + 1)
}

command_b <- function(df, column) {
   df <- dplyr::mutate(df, !!column := !!sym(column) - 1)
}

commander <- function(x) {
   general_command <- function(comm, df, col) {
      if(comm == "a") {
         command_a(x[[df]], col)
      }
      else if (comm == "b") {
         command_b(x[[df]], col)
      }
   }

   purrr::pmap(list(x$commands$command,
                    x$commands$df,
                    x$commands$column),
               general_command)
   return(x)
}

commander(combo)

我被困在最后一点。如何使用pmap或其他类似方法将这些命令映射到列表,但累积更改?我曾考虑过以这种方式使用诸如accumise之类的方法,但由于附加参数未映射,因此不能作为向量,因此显然失败了。

general_command <- function(list, comm, df, col) {
   if(comm == "a") {
      command_a(list[[df]], col)
   }
   else if (comm == "b") {
      command_b(list[[df]], col)
   }
}

commander <- function(x) {
   purrr::accumulate(x,
                    general_command,
                    x$commands$command,
                    x$commands$df,
                    x$commands$column)
   return(x)
}

任何帮助将不胜感激!

0 个答案:

没有答案