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

R:在同一数据帧上多次运行函数,r,function,loops,reduce,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)) 库(dplyr) 此数据我们可以使用for循环 thisdata1 <- thisdata for(i in 2:3){ as

我希望在初始数据帧上多次应用函数。作为一个简单的例子,以以下数据为例:

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

此数据我们可以使用
for
循环

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

thisdata1我们可以为
循环使用

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

thisdata1单独处理多个相同结构的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]])
而且,正如您所料,最终结果是in
out[[n]]

使用
Reduce
,并在
simplefunc
中添加一个废弃的第二个参数,可以稍微简化此过程:

simplefunc <- function(data, ...) {
  datasetfinal2 <- data %>% mutate(varb = varb+1)
  return(datasetfinal2)
}
out <- Reduce(simplefunc, 1:10, init = thisdata, accumulate = TRUE)
尽管您必须将所有其他调用更改为
simplefunc
,以“按名称”而不是按位置(这是一种常见/默认的方式)传递参数

编辑:如果无法(或不想)编辑
simplefunc
,则始终可以使用匿名函数忽略迭代器/计数器:

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

单独处理多个相同结构的数据帧是一种很难管理的方法,尤其是在迭代次数超过几个的情况下。一种流行的“最佳实践”是处理“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]])
而且,正如您所料,最终结果是in
out[[n]]

使用
Reduce
,并在
simplefunc
中添加一个废弃的第二个参数,可以稍微简化此过程:

simplefunc <- function(data, ...) {
  datasetfinal2 <- data %>% mutate(varb = varb+1)
  return(datasetfinal2)
}
out <- Reduce(simplefunc, 1:10, init = thisdata, accumulate = TRUE)
尽管您必须将所有其他调用更改为
simplefunc
,以“按名称”而不是按位置(这是一种常见/默认的方式)传递参数

编辑:如果无法(或不想)编辑
simplefunc
,则始终可以使用匿名函数忽略迭代器/计数器:

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

您知道拥有一个数据帧列表而不是使用
assign
…您知道拥有一个数据帧列表而不是使用
assign
…这可能需要设置一个新问题,但如何将两个数据帧输入reduce函数?(例如,在init点)。我不清楚您打算做什么:如果您的意思是对两个数据帧分别执行此操作,那么只需运行两次(没有其他简单的健壮/弹性方法);如果您指的是两个数据帧的组合,那么这取决于您指的是
rbind
还是
cbind
之类的组合。对不起,是的,有点难以描述。我在这里更详细地概述了这个问题:因此,我主要是寻找将函数的输出反馈到后续迭代中的更大的灵活性。不管怎样,上面的答案非常好。这可能需要设置一个新问题,但是如何将两个数据帧输入reduce函数?(例如,在init点)。我不清楚您打算做什么:如果您的意思是对两个数据帧分别执行此操作,那么只需运行两次(没有其他简单的健壮/弹性方法);如果您指的是两个数据帧的组合,那么这取决于您指的是
rbind
还是
cbind
之类的组合。对不起,是的,有点难以描述。我在这里更详细地概述了这个问题:因此,我主要是寻找将函数的输出反馈到后续迭代中的更大的灵活性。不管怎样,上面的答案非常棒。