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

时间:2017-07-17 01:12:02

标签: r function loops reduce

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

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次,而不必继续调用函数(即.data3)?我最感兴趣的是复制后的最终数据帧,但最好有一个生成的所有数据帧的列表,这样我就可以运行一些诊断。感谢帮助!

2 个答案:

答案 0 :(得分:2)

单独处理多个相同结构的data.frames是一种难以管理的方法,特别是如果迭代次数超过几次。一种流行的“最佳实践”是处理“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”而不是by-position(这是一种常见/默认方式)。

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

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

答案 1 :(得分:0)

我们可以使用for循环

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

注1:最好不要在全局环境中创建单个对象,以便在list内轻松完成操作。

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