R:运行 多次在同一数据帧上运行

R: run function over same dataframe multiple times

我希望在初始数据帧上多次应用一个函数。举个简单的例子,拿这个数据:

library(dplyr)
thisdata <-  data.frame(vara = seq(from = 1, to = 20, by = 1)
                        ,varb = seq(from = 1, to = 20, by = 1))

这是一个简单的函数,我想 运行 覆盖它:

simplefunc <- function(data) {datasetfinal2 <- data %>% mutate(varb = varb+1)
return(datasetfinal2)}
thisdata2 <- simplefunc(thisdata)

thisdata3 <- simplefunc(thisdata2)

那么,我如何 运行 这个函数,比如 10 次,而不必继续调用函数(即 thisdata3)?我最感兴趣的是复制后的最终数据帧,但最好能列出所有生成的数据帧,这样我就可以 运行 进行一些诊断。感谢您的帮助!

我们可以使用 for 循环

thisdata1 <- thisdata
for(i in 2:3){
   assign(paste0('thisdata', i), value = simplefunc(get(paste0('thisdata', i-1))))
 }

注意 1:最好不要在全局环境中创建单独的对象,这样可以在 list 中轻松完成操作。

注意2:之前忘记添加免责声明

单独处理多个相同结构的 data.frames 是一种困难的管理方式,尤其是在迭代次数多的情况下。一个流行的 "best practice" 是处理一个 "list of data.frames",像这样:

n <- 10 # number of times you need to repeat the process
out <- vector("list", n)
out[[1]] <- thisdata
for (i in 2:n) out[[i]] <- simplefunc(out[[i-1]])

您可以使用

查看任何临时值
str(out[[10]])
# 'data.frame': 20 obs. of  2 variables:
#  $ vara: num  1 2 3 4 5 6 7 8 9 10 ...
#  $ varb: num  10 11 12 13 14 15 16 17 18 19 ...

并且,如您所料,最终结果在 out[[n]].

这可以使用 Reduce 稍微简化,并向 simplefunc 添加一个一次性的第二个参数:

simplefunc <- function(data, ...) {
  datasetfinal2 <- data %>% mutate(varb = varb+1)
  return(datasetfinal2)
}
out <- Reduce(simplefunc, 1:10, init = thisdata, accumulate = TRUE)

这有效地做到了:

tmp <- simplefunc(thisdata, 1)
tmp <- simplefunc(tmp, 2)
tmp <- simplefunc(tmp, 3)
# ...

(事实上,如果您查看 Reduce 的来源,它实际上是在执行我上面的第一个建议。)

注意如果simplefunc有其他参数不能去掉,可能:

simplefunc <- function(data, ..., otherarg, anotherarg) {
  datasetfinal2 <- data %>% mutate(varb = varb+1)
  return(datasetfinal2)
}

尽管您必须更改对 simplefunc 的所有其他调用以传递参数 "by-name" 而不是按位置(这是一种 common/default 方式)。

编辑:如果你不能(或不想)编辑simplefunc,你总是可以使用匿名函数来忽略iterator/counter:

Reduce(function(x, ign) simplefunc(x), 1:10, init = thisdata, accumulate = TRUE)