R - вырезать ненулевые значения - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть данные временного ряда в формате таблицы данных (скажем, в нем есть столбцы «дата» и «y»), и я хотел бы разрезать ненулевые значения y в квартили по дате, чтобы каждый квартиль получает метку 1-4, а нулевые значения имеют метку 0. Итак, я знаю, что если бы я просто хотел сделать это для всех значений y, я бы просто запустил:

dt <- dt %>%
      group_by(date) %>%
      mutate(quartile = cut(y, breaks = 4, labels = (1:4)))

Но я не могу понять, как это сделать, чтобы получить метки 0-4, где 0 соответствует 0-значениям y, а 1-4 - квартили в ненулевых значениях.

Редактировать: Чтобы уточнить, я хочу сделать следующее: для каждой даты я хотел бы разделить значения y в этой дате на 5 групп: 1) y = 0, 2) нижние 25% от y (на эту дату), 3) 2-е 25% от y, 3) 3-е 25% от y, 4) верхние 25% от y.

Редактировать 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 в разные даты может быть разным.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Вы можете передать вывод quantile аргументу breaks cut.По умолчанию quantile будет давать квартильные разрывы.

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

Обратите внимание, что минимальное значение по умолчанию исключено.Если вы хотите, чтобы ваши диапазоны вычислялись, включая ноль, то нули будут NA, и вы можете использовать это в своих интересах и использовать is.na, чтобы потом по-другому это трактовать.

Однако, если вы хотите исключить нулиперед вычислением разрывов вам нужно будет немного уменьшить минимальное значение перерыва, чтобы все значения имели метку.Вы можете сделать это, например, используя quantile(x[x>0])-c(1e-10,rep(0,4)).В этом случае нули снова будут отображаться как NA.

0 голосов
/ 11 сентября 2018

По общему признанию, я не совсем уверен, что вы имеете в виду, говоря "обрезание ненулевых значений y в квартили по дате", и, боюсь, у меня недостаточно репутации, чтобы спросить.

Если'date' - это столбец фактической даты, и вы имеете в виду, что 'новая переменная' quartile 'должна указывать, в какой части года y произошла, при условии, что y не равно 0, в этом случае это должно быть 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...