循环返回 NA

问题描述 投票:0回答:1

以下脚本返回“NA”,而不是步骤 2 中定义的径流系数函数。我怀疑这是因为我无法将“日期”列与我的数据关联起来。我必须在不同的时间窗口(在步骤 3 中定义)运行径流系数并循环,以便它可以应用于我的所有站点(在本例中为“Att-Bissen 和 Rau.Merl),变量“PET “未在径流系数函数中使用,但在我的原始数据集中包含它,因此我想将其保留在数据框中。预期的结果是一个数据框,其中包含第 1 列中的所有站点(径流系数)分别从第 2、3 和 4 列中的时间窗口 1、2 和 3 进行计算。

为了重现问题,我创建了以下数据框。

任何帮助将不胜感激!

#Step 1. Define data frame

df <- data.frame(
  stringsAsFactors = FALSE,
  check.names = FALSE,
  Date = c("01/11/1876","01/12/1876",
           "01/01/1877","01/02/1877","01/03/1877",
           "01/04/1877","01/05/1877","01/06/1877",
           "01/07/1877","01/08/1877","01/09/1877",
           "01/10/1877","01/11/1877","01/12/1877",
           "01/01/1878"),
  `Att-Bissen P [mm]` = c(48.5,111.2,29.7,139.4,90.1,25.9,
                          216,94.6,40.5,NA,64.4,68.8,44.7,
                          34.8,71.9),
  `Att-Bissen PET [mm]` = c(88.4,88.3,80.5,53.4,36.7,20.2,
                            21.6,21.7,21.3,37.6,46.1,66.5,89.8,
                            121.5,87.7),
  `Att-Bissen Q [mm]` = c(13.5,12.6,11.3,12.9,44.6,21.3,
                          194.9,NA,49.1,46.7,63.6,25.4,19.8,
                          15.3,16),
  `Rau. Merl P [mm]` = c(43.7,104.2,25.5,131.3,83.7,21.9,
                         205.2,88.1,35.9,61,59,63.2,40,
                         30.4,66.2),
  `Rau. Merl PET [mm]` = c(91.4,91.3,83.2,54.9,37.5,20.3,
                           21.8,21.8,21.4,38.4,47.3,68.6,NA,
                           125.9,90.7),
  `Rau. Merl Q [mm]` = c(8.7,10.6,8.4,14.3,23.7,14.1,
                         131.6,106.7,40.1,42.4,50.3,24.6,16.7,
                         11.3,13.7))

df$Date <- as.Date(df$Date, format = "%d/%m/%Y")


# Step 2. Create the runoff coefficient function using "complete.cases" data
runoff_coef <- function(P, Q) {
  complete_rows <- complete.cases(P, Q)
  P_complete <- P[complete_rows]
  Q_complete <- Q[complete_rows]
  runoffcoef <- (mean(Q_complete))/(mean(P_complete))
  return(data.frame(runoffcoef = runoffcoef))
}

# Step 3. Define time windows
time_windows <- list(
  c("01/11/1876", "01/03/1877"),#time window 1
  c("01/11/1876", "01/09/1877"),# time window 2
  c("01/11/1876", "01/01/1878") #time window 3
)

#Step 4. Extract the name of the sites
site_names <- sub(" P \\[mm\\]| PET \\[mm\\]| Q \\[mm\\]", "", names(df)[-1]) |>
  unique()


# Step 5. Loop through each time window
results <- list()
for (window in time_windows) {
  window_df <- df[df$Date >= window[1] & df$Date <= window[2], ]
  

# Calculate the runoff coefficient for each site in the current time window
  window_results <- list()
  for (site in site_names) {
    site_data <- window_df[, grepl(site, names(window_df))]
    result <- runoff_coef(site_data[[paste0(site, " P [mm]")]], 
                          site_data[[paste0(site, " Q [mm]")]])
    window_results[[site]] <- result
  }
  
  results[[paste(window, collapse = " to ")]] <- window_results
}

# Step 6. Print the results
results

#Step 7. Unlist results
runoff_coefficients <- data.frame(Site = names(results), unlist(results))
r function for-loop time-series na
1个回答
0
投票

df$Date
Date
类,并且
time_windows
的元素都是字符串(并且不是明确的日期格式),因此您的问题从代码块的 middle 开始。它有助于逐行查看事情是否与您预期的不一样。

df <- data.frame(...)
time_windows <- list(...)
site_names <- sub(...) |> unique()

# for (window in time_windows) { 
window <- time_windows[[1]]
window
# [1] "01/11/1876" "01/03/1877"

window_df <- df[df$Date >= window[1] & df$Date <= window[2], ]
window_df
# [1] Date                Att-Bissen P [mm]   Att-Bissen PET [mm] Att-Bissen Q [mm]   Rau. Merl P [mm]    Rau. Merl PET [mm]  Rau. Merl Q [mm]   
# <0 rows> (or 0-length row.names)

如果您将

time_windows
转换为正确的
Date
类,情况就会有所不同。

time_windows <- lapply(time_windows, as.Date, format = "%m/%d/%Y")
time_windows
# [[1]]
# [1] "1876-01-11" "1877-01-03"
# [[2]]
# [1] "1876-01-11" "1877-01-09"
# [[3]]
# [1] "1876-01-11" "1878-01-01"
window <- time_windows[[1]]
window_df <- df[df$Date >= window[1] & df$Date <= window[2], ]
window_df
#         Date Att-Bissen P [mm] Att-Bissen PET [mm] Att-Bissen Q [mm] Rau. Merl P [mm] Rau. Merl PET [mm] Rau. Merl Q [mm]
# 1 1876-11-01              48.5                88.4              13.5             43.7               91.4              8.7
# 2 1876-12-01             111.2                88.3              12.6            104.2               91.3             10.6
# 3 1877-01-01              29.7                80.5              11.3             25.5               83.2              8.4

其余处理应该正常进行。

# after the `for` loop
str(results)
# List of 3
#  $ 1876-01-11 to 1877-01-03:List of 2
#   ..$ Att-Bissen:'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.197
#   ..$ Rau. Merl :'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.16
#  $ 1876-01-11 to 1877-01-09:List of 2
#   ..$ Att-Bissen:'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.197
#   ..$ Rau. Merl :'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.16
#  $ 1876-01-11 to 1878-01-01:List of 2
#   ..$ Att-Bissen:'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.507
#   ..$ Rau. Merl :'data.frame':    1 obs. of  1 variable:
#   .. ..$ runoffcoef: num 0.488

runoff_coefficients <- data.frame(Site = names(results), unlist(results))
runoff_coefficients
#                                                                    Site unlist.results.
# 1876-01-11 to 1877-01-03.Att-Bissen.runoffcoef 1876-01-11 to 1877-01-03       0.1974657
# 1876-01-11 to 1877-01-03.Rau. Merl.runoffcoef  1876-01-11 to 1877-01-09       0.1597463
# 1876-01-11 to 1877-01-09.Att-Bissen.runoffcoef 1876-01-11 to 1878-01-01       0.1974657
# 1876-01-11 to 1877-01-09.Rau. Merl.runoffcoef  1876-01-11 to 1877-01-03       0.1597463
# 1876-01-11 to 1878-01-01.Att-Bissen.runoffcoef 1876-01-11 to 1877-01-09       0.5074551
# 1876-01-11 to 1878-01-01.Rau. Merl.runoffcoef  1876-01-11 to 1878-01-01       0.4882470
© www.soinside.com 2019 - 2024. All rights reserved.