我有一个非常大的数据集(> 1百万行),其中需要计算所有当天的百分位数(例如,所有1月1日,全部是1月2日,...,所有12月31日)。同一年,月和日有许多行,数据不同。以下是数据示例:
Year Month Day A B C D
2007 Jan 1 1 2 3 4
2007 Jan 1 5 6 7 8
2007 Feb 1 1 2 3 4
2007 Feb 1 5 6 7 8
.
.
2010 Dec 30 1 2 3 4
2010 Dec 30 5 6 7 8
2010 Dec 31 1 2 3 4
2010 Dec 31 5 6 7 8
因此,要计算1月1日的第95百分位数,它需要包括所有年份(例如,2007-2010)的所有1月1日以及所有列(A,B,C和D)。然后在1月2日,1月3日,...,12月30日和12月31日完成。通过使用嵌套的if语句,可以使用Excel中的小数据集轻松完成此操作。例如,= {PERCENTILE(IF(月($ B $ 2:$ B $ 1000000)=“Jan”,IF(Day($ C $ 2:$ C $ 1000000)=“1”,$ D $ 2:$ G $ 1000000)), 95%)}
然后可以将百分位数添加到仅包含月份和日期的新数据表中:
Month Day P95 P05
Jan 1
Jan 2
Jan 3
.
.
Dec 30
Dec 31
然后使用百分位数,我需要评估列名A,B,C和D中各自日期(例如,1月1日)的每个数据值是否大于P95或小于P05。然后可以将新列添加到包含1或0的第一个数据表中(如果更大或更小则为1,如果不大于或小于百分位数则为0):
Year Month Day A B C D A05 B05 C05 D05 A95 B95 C95 D95
2007 Jan 1 1 2 3 4 1 0 0 0 0 0 0 0
2007 Jan 1 5 6 7 8 0 0 0 0 0 0 1 1
.
.
2010 Dec 31 5 6 7 8 0 0 0 0 0 0 0 1
答案 0 :(得分:1)
我已将您的数据称为dat
:
library(plyr)
library(reshape2)
# melt values so all values are in 1 column
dat_melt <- melt(dat, id.vars=c("Year", "Month", "Day"), variable.name="letter", value.name="value")
# get quantiles, split by day
dat_quantiles <- ddply(dat_melt, .(Month, Day), summarise,
P05=quantile(value, 0.05), P95=quantile(value, 0.95))
# merge original data with quantiles
all_dat <- merge(dat_melt, dat_quantiles)
# See if in bounds
all_dat <- transform(all_dat, less05=ifelse(value < P05, 1, 0), greater95=ifelse(value > P95, 1, 0))
Month Day Year letter value P05 P95 less05 greater95
1 Dec 30 2010 A 1 1.35 7.65 1 0
2 Dec 30 2010 A 5 1.35 7.65 0 0
3 Dec 30 2010 B 2 1.35 7.65 0 0
4 Dec 30 2010 B 6 1.35 7.65 0 0
5 Dec 30 2010 C 3 1.35 7.65 0 0
6 Dec 30 2010 C 7 1.35 7.65 0 0
7 Dec 30 2010 D 4 1.35 7.65 0 0
8 Dec 30 2010 D 8 1.35 7.65 0 1
9 Dec 31 2010 A 1 1.35 7.65 1 0
10 Dec 31 2010 A 5 1.35 7.65 0 0
11 Dec 31 2010 B 2 1.35 7.65 0 0
12 Dec 31 2010 B 6 1.35 7.65 0 0
13 Dec 31 2010 C 3 1.35 7.65 0 0
14 Dec 31 2010 C 7 1.35 7.65 0 0
15 Dec 31 2010 D 4 1.35 7.65 0 0
16 Dec 31 2010 D 8 1.35 7.65 0 1
17 Feb 1 2007 A 1 1.35 7.65 1 0
18 Feb 1 2007 A 5 1.35 7.65 0 0
19 Feb 1 2007 B 2 1.35 7.65 0 0
20 Feb 1 2007 B 6 1.35 7.65 0 0
21 Feb 1 2007 C 3 1.35 7.65 0 0
22 Feb 1 2007 C 7 1.35 7.65 0 0
23 Feb 1 2007 D 4 1.35 7.65 0 0
24 Feb 1 2007 D 8 1.35 7.65 0 1
25 Jan 1 2007 A 1 1.35 7.65 1 0
26 Jan 1 2007 A 5 1.35 7.65 0 0
27 Jan 1 2007 B 2 1.35 7.65 0 0
28 Jan 1 2007 B 6 1.35 7.65 0 0
29 Jan 1 2007 C 3 1.35 7.65 0 0
30 Jan 1 2007 C 7 1.35 7.65 0 0
31 Jan 1 2007 D 4 1.35 7.65 0 0
32 Jan 1 2007 D 8 1.35 7.65 0 1
答案 1 :(得分:0)
这些行中的某些内容可以合并到原始数据框:
aggregate(dfrm[ , c("A","B","C","D")] , list(dfrm$month, dfrm$day),
FUN=quantile, probs=c(0.05,0.95))
注意我建议merge()
。您的描述建议(但不明确)您希望所有年份的Jan-1值一起提交。我认为这比你在Excel中使用的表达“更容易”。这在所有四列上均为0.05和0.95。