首页 > 解决方案 > R - 剪切非零值

问题描述

我有一个数据表格式的时间序列数据(假设它有“日期”和“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 的第 2 25%,3) y 的第 3 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 分布可能不同。

标签: r

解决方案


诚然,我不确定您所说的“将 y 的非零值按日期分成四分位数”是什么意思,恐怕我没有足够的声誉来问。

如果 'date' 是一个实际的日期列,并且您的意思是,“新变量 'quartile' 应该指示 y 发生在一年中的哪个部分,假设 y 不为 0,在这种情况下它应该为 0”,我' d 这样做:

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))

推荐阅读