gpt4 book ai didi

r - 摆脱嵌套的(不必要的?)for 循环

转载 作者:行者123 更新时间:2023-12-04 11:45:43 24 4
gpt4 key购买 nike

我在 Fortran 方面经验丰富,但在 R 方面还是个新手。在 Fortran 中,我习惯嵌套几个 do-loops,但我想 R 中有更好的方法。一些其他问题通过应用 apply,但我不确定这是否适合我。

我想对我的模型数据进行偏差校正。我知道为此存在软件包,但我更愿意自己编写代码。我有两个 data.frames,第一个包含我的模型数据:

library(dplyr)
x <- round(runif(34698,0,20), 2)
df_a <- data.frame(date=as.Date(0:34697, origin="2006-01-01"),x)
df_a <- setNames(df_a, c("date","daily"))
df_a <- separate(df_a, date, into = c("year", "month", "day"), sep="-")

第二个数据框包含观察到的和建模的历史月均值:

df_b <- data.frame(month=seq(01,12,by=1),obs=seq(1.1,12.1,by=1),model=seq(2.2,13.2,by=1))
df_b$month <- ifelse(nchar(df_b$month)!=2,paste0("0",df_b$month),df_b$month)

使用以下代码,我使用第二个 data.frame 的每个月的平均值来更正我的第一个 data.frame 的数据。代码运行良好,但我认为这不是 R 风格的编码方式。特别是,我需要更多的 for 循环,因为我有多个模型输出,并且对于每个模型,我都有两个不同的场景。

system.time(
for(i in 1:12){
for (j in 1:nrow(df_a)) {
if(df_b$month[i]==df_a$month[j]){
df_a$daily[j] <- df_a$daily[j]+(df_b$obs[i]-df_b$model[i])
}
}
}
)

如果有人能告诉我如何“改进”我在 R 中的编码风格,我将不胜感激。

最佳答案

更好的选择是执行 left_joinmutate 来创建新列

library(dplyr)
df_a1 <- df_a %>%
left_join(df_b) %>%
mutate(daily = daily + obs + model)

基准

system.time(df_a %>% 
left_join(df_b) %>%
mutate(daily = daily + obs + model))
# user system elapsed
# 0.201 0.011 0.213

另外,正如@parfait 在评论中提到的那样,一个带有mergebase R 版本将是

system.time( within(merge(df_a, df_b, by="month", all.x=TRUE), {
daily <- daily + obs + model}))
# user system elapsed
# 0.260 0.015 0.275

或者用data.table

library(data.table)
system.time(setDT(df_a)[df_b, daily := daily + obs + model, on = .(month)])
# user system elapsed
# 0.198 0.011 0.208

和 OP 的 for 循环

system.time(
for(i in 1:12){
for (j in 1:nrow(df_a)) {
if(df_b$month[i]==df_a$month[j]){
df_a$daily[j] <- df_a$daily[j]+(df_b$obs[i]-df_b$model[i])
}
}
}
)
# user system elapsed
# 9.661 2.741 12.306

关于r - 摆脱嵌套的(不必要的?)for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54238242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com