我希望多次在初始数据帧上应用函数。举个简单的例子,拿这个数据:
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)?我最感兴趣的是复制后的最终数据帧,但最好有一个生成的所有数据帧的列表,这样我就可以运行一些诊断。感谢帮助!
答案 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:忘记提前添加免责声明