我有一个数据表格式的时间序列数据(假设它具有“ date”和“ y”列),我想按日期将y的非零值切成四分位数,这样每个四分位数得到标签1-4,零值得到标签0。所以我知道,如果我只想对所有y值都这样做,我将运行:
dt <- dt %>%
group_by(date) %>%
mutate(quartile = cut(y, breaks = 4, labels = (1:4)))
但是我不知道如何获取标签0-4,其中0分配给y的0值,而1-4是非零值的四分位数。
编辑:为明确起见,我想做的是以下操作:对于每个日期,我想将该日期中y的值分为5组:1)y = 0,2)y的底25% (在该日期),3)y的第二25%,3)y的第三25%,4)y的前25%。
编辑2: 因此,我为此找到了2种解决方案:
dt[,quartile := cut(y, quantile(dt[y>0]$y, probs = 0:4/4),
labels = (1:4)), by = date]
和
dt %>%
group_by(date) %>%
mutate(quartile = findInterval(y, quantile(dta[y>0]$y,
probs= 0:4/4)))
但是,这两种方法似乎都是先计算整个数据的断点,然后再按日期切割数据。但我希望根据日期来计算断点,因为obs分布在不同的日期可能会有所不同。
答案 0 :(得分:0)
我不知道您不确定“按日期将y的非零值切成四分位数”是什么意思,而且我恐怕没有足够的声誉来询问了。
如果'date'是实际的日期列,并且您的意思是,“假设y不为0,则新变量'四分位数'应该指示y发生在哪一年,在这种情况下,它应该为0” ,我会这样:
library(dplyr)
library(lubridate)
# create example
dt <- data.frame(y = c(0, 1, 3, 4), date = c("01-02-18", "01-06-18",
"01-12-16", "01-04-17"))
dt <- dt %>%
## change 'date' to an actual date
mutate(date = as_date(date)) %>%
## extract the quarter
mutate(quartile = quarter(date)) %>%
## replace all quarters with 0 where y was 0
mutate(quartile = if_else(y == 0, 0, as.double(quartile)))`
编辑:我想我现在已经明白了这个问题。这可能有点冗长,但是我认为它可以满足您的要求:
library(dplyr)
dt <- tibble(y = c(20, 30, 40, 20, 30, 40, 0), date = c("01-02-16",
"01-02-16", "01-02-16", "01-08-18", "01-08-18", "01-08-18",
"01-08-18"))
new_dt <- dt %>%
# filter out all cases where y is greater than 0
filter(y > 0) %>%
# group by date
group_by(date) %>%
# cut the y values per date
mutate(quartile = cut(y, breaks = 4, labels = c(1:4)))
dt <- dt %>%
# take the original dt, add in the newly calculated quartiles
full_join(new_dt, by = c("y", "date")) %>%
# replace the NAs by 0
mutate(quartile = ifelse (is.na(quartile), 0, quartile))
答案 1 :(得分:0)
您可以将{...props}
的输出传递给quantile
的breaks参数。默认情况下,cut
将产生四分位数中断。
quantile
请注意,默认情况下不包含最小值。如果要计算包含零的范围,则零将是NA,您可以利用它来发挥自己的优势,然后使用x <- rpois(100,4)
table(x)
x
0 1 2 3 4 5 6 7 8 9 10 12
1 7 17 19 17 18 12 5 1 1 1 1
cut(x,breaks=quantile(x),labels=1:4)
[1] 2 2 2 1 2 1 1 2 3 3 1 4 1 4 1
[16] 2 4 2 4 2 3 1 4 1 2 2 1 1 2 2
[31] 1 2 2 3 4 1 4 2 2 1 2 4 4 3 1
[46] 3 1 1 3 3 2 4 2 2 1 2 2 4 1 1
[61] 1 2 2 4 4 3 3 2 1 1 3 2 3 2 3
[76] 2 4 2 <NA> 2 3 2 4 2 1 4 4 3 4 1
[91] 2 4 3 2 2 3 4 4 3 2
Levels: 1 2 3 4
将其区别对待。
但是,如果要在计算中断之前排除零,则需要稍微减小最小中断值以确保所有值都被赋予标签。例如,您可以使用is.na
来完成此操作。在这种情况下,零将再次显示为NA。