Найти DOY, соответствующий данному процентилю - PullRequest
0 голосов
/ 01 июня 2018

У меня есть фрейм данных с ежедневными значениями NDVI с 2013 по 2017 год. Мой фрейм данных содержит непрерывные данные 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)

Я использую функции quantile и tapply, чтобы найти для каждого года в кадре данных значение NDVI, соответствующее 10-му, 30-му, 50-му и 80-му процентилю:

quantile=do.call("rbind", tapply(df$NDVI, df$year, quantile,c(0.10, 0.30, 0.50, 0.80)))

Мой вопрос:Как найти DOY, соответствующий 10-му, 30-му, 50-му, 80-му процентилю значений NDVI для каждого года?Например, если значение NDVI 0,3 соответствует 50-му процентилю 2014 года, я хотел бы вернуть DOY, соответствующий NDVI 0,3.

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Это решение, аналогичное Лену, и я повторяю то, что они говорят о трудностях точного совпадения.Я использовал то же самое семя, чтобы сделать результаты сопоставимыми.Разница в том, что я держу квантили в длинной форме, что облегчает этап фильтрации.

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  
0 голосов
/ 01 июня 2018

Проблема в том, что иногда процентиль не соответствует истинному наблюдению в NDVI.В этих случаях среднее значение принимает значения NDVI, например, около 30-го процентиля для года X. В этих случаях я взял два значения NDVI, которые являются ближайшими к значениям 30-го процентиля, вы можете выбрать оба или взятьсреднее значение соответствующих значений 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
...