在R中,是否可以在多个组中包含相同的行,还是有其他解决方法?

时间:2015-11-18 18:30:03

标签: r dplyr lubridate

我在当天的多个时间点(不是等间距)测量了来自土壤的N2O通量。我试图通过找到给定日期的曲线下面积来计算一小部分天土壤的总N20通量。我知道如何仅使用给定日期的测量值,但是,我想包括前一天的最后一个测量值和第二天的第一个测量值,以改善曲线的估计。

这是一个提供更具体想法的例子:

library(MESS)
library(lubridate)
library(dplyr)

生成可重复的示例

datetime <- seq(ymd_hm('2015-04-07 11:20'),ymd('2015-04-13'), by = 'hours')
dat <- data.frame(datetime, day = day(datetime), Flux = rnorm(n = length(datetime), mean = 400, sd = 20))

useDate <- data.frame(day = c(7:12), DateGood = c("No", "Yes", "Yes", "No", "Yes", "No"))
  dat <- left_join(dat, useDate)

有些日子不好&#34; (太多缺少措施),有些是&#34;好&#34; (可用)。目标是过滤在&#34; Good&#34;上发生的所有测量(行)。日,以及前一天的最后一次测量和第二天的第一次测量。

  out <- dat %>%
      mutate(lagDateGood = lag(DateGood),
             leadDateGood = lead(DateGood)) %>%
      filter(lagDateGood != "No" | leadDateGood != "No")

现在我需要计算曲线下的面积 - 这是不正确的

out2 <- out %>%
    group_by(day) %>%
    mutate(hourOfday = hour(datetime) + minute(datetime)/60) %>%
    summarize(auc = auc(x = hourOfday, y = Flux, from = 0, to = 24, type = "spline"))

问题在于,在计算AUC时,我不会在前一天结束时和第二天开始时包括测量结果。此外,我得到了第10天的通量估计值,这是一个很糟糕的&#34;一天。

我认为我的问题的症结与群体有关。一些测量需要在多个组中(例如,第8天的最后一次测量将用于估计第8天和第9天的AUC)。你对我如何组建新团队有什么建议吗?或者可能有完全不同的方式来实现目标?

2 个答案:

答案 0 :(得分:0)

对于它的价值,这就是我所做的。答案真正在于我在评论中链接的问题。从问题的数据框“out”开始:

#Now I need to calculate the area under the curve for each day
n <- nrow(out)
extract <- function(ix) out[seq(max(1, min(ix)-1), min(n, max(ix) + 1)), ]
res <- lapply(split(1:n, out$day), extract)

calcTotalFlux <- function(df) {
    if (nrow(df) < 10) {              # make sure the day has at least 10 measures
        NA
    } else {
    day_midnight <- floor_date(df$datetime[2], "day")
    df %>%
    mutate(time = datetime - day_midnight) %>%
    summarize(TotalFlux = auc(x = time, y = Flux, from = 0, to = 1440, type = "spline"))}
}

do.call("rbind",lapply(res, calcTotalFlux))

    TotalFlux
7         NA
8   585230.2
9   579017.3
10        NA
11  563689.7
12        NA

答案 1 :(得分:0)

这是另一种方式。更符合@Alex Brown的建议。

 # Another way
last <- out %>%
    group_by(day) %>%
    filter(datetime == max(datetime)) %>%
    ungroup() %>%
    mutate(day = day + 1)

first <- out %>%
    group_by(day) %>%
    filter(datetime == min(datetime)) %>%
    ungroup() %>%
    mutate(day = day - 1)

d <- rbind(out, last, first) %>%
    group_by(day) %>%
    arrange(datetime)

n_measures_per_day <- d %>%
    summarize(n = n())

d <- left_join(d, n_measures_per_day) %>%
    filter(n > 4)

TotalFluxDF <- d %>%
    mutate(timeAtMidnight = floor_date(datetime[3], "day"),
           time = datetime - timeAtMidnight) %>%
    summarize(auc = auc(x = time, y = Flux, from = 0, to = 1440, type = "spline"))

TotalFluxDF

Source: local data frame [3 x 2]

    day      auc
  (dbl)    (dbl)
1     8 585230.2
2     9 579017.3
3    11 563689.7