查找与给定百分位数对应的 DOY
Find DOY corresponding to a given percentile
我有一个包含 2013 年到 2017 年每日 NDVI 值的数据框。
我的数据框有连续的 NDVI 数据(即一年中的每一天),但这是我的数据框结构的可重现示例:
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- cbind(year,DOY,NDVI)
我使用分位数和 tapply 函数为数据框中的每一年查找对应于第 10、30、50 和 80 个百分位数的 NDVI 值:
quantile=do.call("rbind", tapply(df$NDVI, df$year, quantile,c(0.10, 0.30, 0.50, 0.80)))
我的问题是:如何找到每年NDVI值的第10、30、50、80个百分位数对应的DOY?例如,如果 NDVI 值 0.3 对应于 2014 年的第 50 个百分位数,我想 return 对应于 NDVI 0.3 的 DOY。
感谢您的帮助!
问题是,有时百分位数与 NDVI 中的真实观察不匹配。在这些情况下,平均值是 NDVI 值的取值,例如 X 年的第 30 个百分位数。在这些情况下,我取了两个最接近第 30 个百分位数的 NDVI 值,您可以选择同时选择两者或取相应的 DOY 值的平均值。也许这是一个小的解决方法,但这是我现在能想到的最好的方法:
set.seed(1)
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- as.data.frame(cbind(year,DOY,NDVI))
library(dplyr)
library(tidyr)
library(broom)
df %>%
group_by(year) %>%
do( tidy(t(quantile(.$NDVI, c(0.10, 0.30, 0.50, 0.80)))) ) %>%
ungroup() %>%
right_join(df) %>%
arrange(year, NDVI) %>%
group_by(year) %>%
filter(abs(X10. - NDVI) == min(abs(X10. - NDVI)) |
abs(X30. - NDVI) == min(abs(X30. - NDVI)) |
abs(X50. - NDVI) == min(abs(X50. - NDVI))|
abs(X80. - NDVI) == min(abs(X80. - NDVI)))
给出:
year X10. X30. X50. X80. DOY NDVI
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013. -0.844 -0.459 -0.0144 0.583 247. -0.844
2 2013. -0.844 -0.459 -0.0144 0.583 96. -0.447
3 2013. -0.844 -0.459 -0.0144 0.583 202. -0.0144
4 2013. -0.844 -0.459 -0.0144 0.583 59. 0.584
5 2014. -0.811 -0.403 -0.0136 0.623 128. -0.818
6 2014. -0.811 -0.403 -0.0136 0.623 37. -0.410
7 2014. -0.811 -0.403 -0.0136 0.623 187. -0.0136
8 2014. -0.811 -0.403 -0.0136 0.623 278. 0.620
9 2015. -0.890 -0.494 -0.0332 0.646 280. -0.887
10 2015. -0.890 -0.494 -0.0332 0.646 330. -0.488
这是与 Len 的解决方案类似的解决方案,我重申他们所说的进行精确匹配的困难。我使用相同的种子来使结果具有可比性。不同之处在于我将分位数保留为长格式,这使得过滤步骤更容易。
library("tidyverse")
set.seed(1)
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- data_frame(year,DOY,NDVI)
df %>% group_by(year) %>%
do(data_frame(p = c(10, 30, 50, 80)/100, q = quantile(.$NDVI, probs = p))) %>%
full_join(df) %>%
group_by(year, p) %>%
slice(which.min(abs(NDVI - q)))
# A tibble: 20 x 5
# Groups: year, p [20]
year p q DOY NDVI
<int> <dbl> <dbl> <int> <dbl>
1 2013 0.100 -0.844 247 -0.844
2 2013 0.300 -0.459 96 -0.447
3 2013 0.500 -0.0144 202 -0.0144
4 2013 0.800 0.583 59 0.584
5 2014 0.100 -0.811 128 -0.818
6 2014 0.300 -0.403 37 -0.410
7 2014 0.500 -0.0136 187 -0.0136
8 2014 0.800 0.623 278 0.620
9 2015 0.100 -0.890 280 -0.887
10 2015 0.300 -0.494 330 -0.488
11 2015 0.500 -0.0332 316 -0.0332
12 2015 0.800 0.646 190 0.647
13 2016 0.100 -0.803 351 -0.803
14 2016 0.300 -0.447 206 -0.447
15 2016 0.500 -0.00170 122 -0.00170
16 2016 0.800 0.548 353 0.548
17 2017 0.100 -0.824 326 -0.830
18 2017 0.300 -0.484 124 -0.483
19 2017 0.500 -0.00704 175 -0.00900
20 2017 0.800 0.573 95 0.570
我有一个包含 2013 年到 2017 年每日 NDVI 值的数据框。 我的数据框有连续的 NDVI 数据(即一年中的每一天),但这是我的数据框结构的可重现示例:
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- cbind(year,DOY,NDVI)
我使用分位数和 tapply 函数为数据框中的每一年查找对应于第 10、30、50 和 80 个百分位数的 NDVI 值:
quantile=do.call("rbind", tapply(df$NDVI, df$year, quantile,c(0.10, 0.30, 0.50, 0.80)))
我的问题是:如何找到每年NDVI值的第10、30、50、80个百分位数对应的DOY?例如,如果 NDVI 值 0.3 对应于 2014 年的第 50 个百分位数,我想 return 对应于 NDVI 0.3 的 DOY。
感谢您的帮助!
问题是,有时百分位数与 NDVI 中的真实观察不匹配。在这些情况下,平均值是 NDVI 值的取值,例如 X 年的第 30 个百分位数。在这些情况下,我取了两个最接近第 30 个百分位数的 NDVI 值,您可以选择同时选择两者或取相应的 DOY 值的平均值。也许这是一个小的解决方法,但这是我现在能想到的最好的方法:
set.seed(1)
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- as.data.frame(cbind(year,DOY,NDVI))
library(dplyr)
library(tidyr)
library(broom)
df %>%
group_by(year) %>%
do( tidy(t(quantile(.$NDVI, c(0.10, 0.30, 0.50, 0.80)))) ) %>%
ungroup() %>%
right_join(df) %>%
arrange(year, NDVI) %>%
group_by(year) %>%
filter(abs(X10. - NDVI) == min(abs(X10. - NDVI)) |
abs(X30. - NDVI) == min(abs(X30. - NDVI)) |
abs(X50. - NDVI) == min(abs(X50. - NDVI))|
abs(X80. - NDVI) == min(abs(X80. - NDVI)))
给出:
year X10. X30. X50. X80. DOY NDVI
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013. -0.844 -0.459 -0.0144 0.583 247. -0.844
2 2013. -0.844 -0.459 -0.0144 0.583 96. -0.447
3 2013. -0.844 -0.459 -0.0144 0.583 202. -0.0144
4 2013. -0.844 -0.459 -0.0144 0.583 59. 0.584
5 2014. -0.811 -0.403 -0.0136 0.623 128. -0.818
6 2014. -0.811 -0.403 -0.0136 0.623 37. -0.410
7 2014. -0.811 -0.403 -0.0136 0.623 187. -0.0136
8 2014. -0.811 -0.403 -0.0136 0.623 278. 0.620
9 2015. -0.890 -0.494 -0.0332 0.646 280. -0.887
10 2015. -0.890 -0.494 -0.0332 0.646 330. -0.488
这是与 Len 的解决方案类似的解决方案,我重申他们所说的进行精确匹配的困难。我使用相同的种子来使结果具有可比性。不同之处在于我将分位数保留为长格式,这使得过滤步骤更容易。
library("tidyverse")
set.seed(1)
year <- sample(2013:2017, 750,replace=TRUE)
DOY <- sample(1:365, 750,replace=TRUE)
NDVI<- runif(750, -1, 1)
df <- data_frame(year,DOY,NDVI)
df %>% group_by(year) %>%
do(data_frame(p = c(10, 30, 50, 80)/100, q = quantile(.$NDVI, probs = p))) %>%
full_join(df) %>%
group_by(year, p) %>%
slice(which.min(abs(NDVI - q)))
# A tibble: 20 x 5
# Groups: year, p [20]
year p q DOY NDVI
<int> <dbl> <dbl> <int> <dbl>
1 2013 0.100 -0.844 247 -0.844
2 2013 0.300 -0.459 96 -0.447
3 2013 0.500 -0.0144 202 -0.0144
4 2013 0.800 0.583 59 0.584
5 2014 0.100 -0.811 128 -0.818
6 2014 0.300 -0.403 37 -0.410
7 2014 0.500 -0.0136 187 -0.0136
8 2014 0.800 0.623 278 0.620
9 2015 0.100 -0.890 280 -0.887
10 2015 0.300 -0.494 330 -0.488
11 2015 0.500 -0.0332 316 -0.0332
12 2015 0.800 0.646 190 0.647
13 2016 0.100 -0.803 351 -0.803
14 2016 0.300 -0.447 206 -0.447
15 2016 0.500 -0.00170 122 -0.00170
16 2016 0.800 0.548 353 0.548
17 2017 0.100 -0.824 326 -0.830
18 2017 0.300 -0.484 124 -0.483
19 2017 0.500 -0.00704 175 -0.00900
20 2017 0.800 0.573 95 0.570