我有一个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百分位数,我想返回对应于NDVI为0.3的DOY。
感谢您的帮助!
答案 0 :(得分:1)
问题是,有时百分位数与NDVI中的真实观察结果不匹配。在这些情况下,平均值是NDVI值的变量,例如X年的第30个百分位数。在这些情况下,我采用了最接近第30个百分点的两个NDVI值,您可以选择同时选择两者或采取相应DOY值的平均值。也许这是一个小小的解决方法,但这是我现在能想到的最好的方法:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String db_file = "word504.db" ;
String db_path= this.getDatabasePath(db_file ).getPath();
File dbFile = new File(db_path);
if(!dbFile.exists())
{
try
{
copyFileFromAssets(db_file, db_path);
}
catch (IOException e) {
Log.e("***********" , ""+ e.getMessage());
}
}
}
private void copyFileFromAssets(String name,String dest) throws IOException
{
InputStream mInput = this.getAssets().open(name);
OutputStream mOutput = new FileOutputStream(dest);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
}
给出了:
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)))
答案 1 :(得分:1)
这与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