根据日期计算不同列的平均值

问题描述 投票:2回答:2

我的数据集是关于森林大火和NDVI值(该值介于0到1之间,表示表面的绿色程度)。它有一个初始列,该列表示第一行的森林大火发生的时间,随后的列指示大火发生前后不同日期的NDVI值。火灾前的NDVI值比火灾后的NDVI值高得多。类似于:

data1989 <- data.frame("date_fire" = c("1987-01-01", "1987-07-03", "1988-01-01"), 
                       "1986-01-01" = c(0.5, 0.589, 0.66), 
                       "1986-06-03" = c(0.56, 0.447, 0.75), 
                       "1986-10-19" = c(0.8, NA, 0.83),
                       "1987-01-19" = c(0.75, 0.65,0.75), 
                       "1987-06-19" = c(0.1, 0.55,0.811),
                       "1987-10-19" = c(0.15, 0.12, 0.780),
                       "1988-01-19" = c(0.2, 0.22,0.32), 
                       "1988-06-19" = c(0.18, 0.21,0.23),
                       "1988-10-19" = c(0.21, 0.24, 0.250),
                       stringsAsFactors = FALSE) 
> data1989
   date_fire X1986.01.01 X1986.06.03 X1986.10.19 X1987.01.19 X1987.06.19 X1987.10.19 X1988.01.19 X1988.06.19 X1988.10.19
1 1987-01-01       0.500       0.560        0.80        0.75       0.100        0.15        0.20        0.18        0.21
2 1987-07-03       0.589       0.447          NA        0.65       0.550        0.12        0.22        0.21        0.24
3 1988-01-01       0.660       0.750        0.83        0.75       0.811        0.78        0.32        0.23        0.25

我想在森林火灾之前的新列中计算NDVI值的平均值。在第一种情况下,它将是第2、3、4和5列的平均值。

我需要得到的是:

date_fire    X1986.01.01 X1986.06.03 X1986.10.19 X1987.01.19 X1987.06.19 X1987.10.19 X1988.01.19 X1988.06.19 X1988.10.19 meanPreFire
1 1987-01-01       0.500       0.560        0.80        0.75       0.100        0.15        0.20        0.18        0.21       0.653
2 1987-07-03       0.589       0.447          NA        0.65       0.550        0.12        0.22        0.21        0.24       0.559
3 1988-01-01       0.660       0.750        0.83        0.75       0.811        0.78        0.32        0.23        0.25       0.764

谢谢!

r date mean
2个回答
4
投票

将数据重整为长格式并在森林大火之前过滤日期。

library(tidyverse)

data1989 %>%
  pivot_longer(-date_fire, names_to = "date") %>%
  mutate(date_fire = as.Date(date_fire),
         date = as.Date(date, "X%Y.%m.%d")) %>%
  filter(date < date_fire) %>%
  group_by(date_fire) %>%
  summarise(meanPreFire = mean(value, na.rm = T))

# # A tibble: 3 x 2
#   date_fire  meanPreFire
#   <date>           <dbl>
# 1 1987-01-01       0.62 
# 2 1987-07-03       0.559
# 3 1988-01-01       0.764

3
投票

如果我们将数据保留为长(更)格式,则解决方案会更加简洁...但这将重现所需的输出:

library(dplyr)
library(tidyr)
data1989 %>% 
  pivot_longer(-date_fire, names_to = "date_NDVI", values_to = "value", names_prefix = "^X") %>% 
  mutate(date_fire = as.Date(date_fire, "%Y-%m-%d"),
         date_NDVI = as.Date(date_NDVI, "%Y.%m.%d")) %>% 
  group_by(date_fire) %>% 
  mutate(period = ifelse(date_NDVI < date_fire, "before_fire", "after_fire")) %>% 
  group_by(date_fire, period) %>% 
  mutate(average_NDVI = mean(value, na.rm = TRUE)) %>% 
  pivot_wider(names_from = date_NDVI,  names_prefix = "X", values_from = value) %>% 
  pivot_wider(names_from = period, values_from = average_NDVI) %>% 
  group_by(date_fire) %>% 
  summarise_all(funs(sum(., na.rm=T)))

返回:

# A tibble: 3 x 12
  date_fire  `X1986-01-01` `X1986-06-03` `X1986-10-19` `X1987-01-19` `X1987-06-19` `X1987-10-19` `X1988-01-19` `X1988-06-19` `X1988-10-19` before_fire after_fire
  <date>             <dbl>         <dbl>         <dbl>         <dbl>         <dbl>         <dbl>         <dbl>         <dbl>         <dbl>       <dbl>      <dbl>
1 1987-01-01         0.5           0.56           0.8           0.75         0.1            0.15          0.2           0.18          0.21       0.62       0.265
2 1987-07-03         0.589         0.447          0             0.65         0.55           0.12          0.22          0.21          0.24       0.559      0.198
3 1988-01-01         0.66          0.75           0.83          0.75         0.811          0.78          0.32          0.23          0.25       0.764      0.267

编辑:

如果我们在计算平均值后立即停止表达式,我们可以使用此结构中的数据轻松计算方差或解释观察次数的变化。我认为可以将date_fire保留为自己的列,但我建议将其他日期保留为一列(因为它们对应于观察值)。特别是如果我们想使用ggplot2和其他tidyverse函数对数据进行更多分析。

© www.soinside.com 2019 - 2024. All rights reserved.