【问题标题】:Find DOY corresponding to a given percentile查找对应于给定百分位数的 DOY
【发布时间】:2018-11-11 03:38:18
【问题描述】:

我有一个数据框,其中包含 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)

我使用 quantile 和 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 个百分位,我想返回对应于 0.3 的 NDVI 的 DOY。

感谢您的帮助!

【问题讨论】:

    标签: r percentile


    【解决方案1】:

    问题是,有时百分位数与 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
    

    【讨论】:

    • 非常感谢!这很有帮助!
    【解决方案2】:

    这与 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  
    

    【讨论】:

    • 我一直在寻找这样的东西,以使我的解决方案也以整洁的格式出现,但这次无法提出。谢谢!
    猜你喜欢
    • 2017-01-27
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多