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)
我希望在初始数据帧上多次应用一个函数。举个简单的例子,拿这个数据:
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)