Подмножество кадра данных на основе уровней фактора и создание новой переменной квантилей, зависящих от переменной в подмножестве

У меня есть кадр данных, например:

set.seed(567) 
year= as.factor(c(rep("1998", 20), rep("1999", 16)))
lepsp= c(letters[seq(from = 1, to = 20 )], c('a','b','c'),letters[seq(from =8, to = 20 )]) 
freq= rpois(36, lambda=12)
df<-data.frame(year, lepsp, freq)

df<- 
  df %>%
  group_by(year) %>%
  mutate(rank = dense_rank(-freq))

Я хотел бы разделить df на year и создать новый столбец с именем quant, который присваивает соответствующий квартиль каждому значению freq в подмножестве. В новом столбце можно назначить квантиль как probs = seq(0, 1, 0.05). Самое главное, что позже я могу назначать категории на основе квантиля, так что, например, все, что ниже 25%, классифицируется как редкое. Таким образом, это могут быть общие обозначения квартилей, но чем меньше приращение процентилей, тем больше «пространства для маневра» у меня будет, чтобы классифицировать что-то как редкое r или обычное c.

Вывод должен выглядеть так:

df<-data.frame(df, quant= c(75,50,25,50,50,25,75,50,25,75,75,100,50,100,100,50,25,25,75,25,75,50,50,75,75,25,25,50,50,50,25,75,75,25,75,50), 
               abucat= c("c", "r", "r","r","r", "r","c","r","r", "c", "c", "c", "r","c", "c","r" , "r", "r", "c", "r", "c","r","r","c","c","r",
 "r","r","r","r","r","c","c","r","c","r"))

Я пытался:

library(dplyr)

df<- 
  df %>%
  group_by(year) %>%
  mutate(quant = quantile(freq, probs= seq(0, 1, 0.25)))

person Danielle    schedule 31.05.2018    source источник
comment
Как вы рассчитываете свое количественное значение?   -  person jasbner    schedule 31.05.2018
comment
Сначала я подмножал каждый год sub1998 и sub1999 и использовал quantile(sub1998$freq) и quantile(sub1999$freq) таким образом, что для sub1998, если freq было меньше 6, это = 25%, меньше 11, но больше 6= 50% меньше 12,25, но больше 11= 75% и так далее. больше 12,25 = 100%   -  person Danielle    schedule 31.05.2018
comment
тогда почему вторая частота 1998 года 13 имеет квант 50 в вашем выводе?   -  person jasbner    schedule 31.05.2018
comment
Блин, я забыл set.seed() ... я думаю, что проблема в этом. Я отредактирую сообщение, чтобы мой вывод соответствовал исходному df.   -  person Danielle    schedule 31.05.2018
comment
Вы также можете использовать dput для публикации своего фрейма данных, если у вас возникли проблемы с его созданием с нуля.   -  person jasbner    schedule 31.05.2018


Ответы (1)


Я обновил код, чтобы использовать case_when, чтобы сделать его более интуитивным. Вы должны увидеть каждый из случаев, когда классифицируется quant, и соответствующие значения. Затем я использую tidyr, чтобы разделить его на 2 столбца.

library(dplyr)
library(tidyr)
set.seed(567) 
year= as.factor(c(rep("1998", 20), rep("1999", 16)))
lepsp= c(letters[seq(from = 1, to = 20 )], c('a','b','c'),letters[seq(from =8, to = 20 )]) 
freq= rpois(36, lambda=12)
df<-data.frame(year, lepsp, freq)

df<- 
  df %>%
  group_by(year) %>%
  mutate(rank = dense_rank(-freq))

df<-data.frame(df, quant= c(75,50,25,50,50,25,75,50,25,75,75,100,50,100,100,50,25,25,75,25,75,50,50,75,75,25,25,50,50,50,25,75,75,25,75,50), 
               abucat= c("c", "r", "r","r","r", "r","c","r","r", "c", "c", "c", "r","c", "c","r" , "r", "r", "c", "r", "c","r","r","c","c","r",
                         "r","r","r","r","r","c","c","r","c","r"))

df %>%
  group_by(year) %>%
  mutate(qtile = list(quantile(freq))) %>% 
  rowwise() %>% 
  mutate(q = case_when(freq <= qtile[2] ~ "25,r",
                           freq > qtile[2] & freq <=qtile[3] ~"50,r",
                           freq > qtile[3] & freq <=qtile[4] ~"75,c",
                           freq > qtile[4] ~ "100,c")) %>% 
  separate(q, c("quant","abucat")) %>% 
  select(-qtile)
#  Source: local data frame [36 x 6]
#  Groups: <by row>
#  
#  # A tibble: 36 x 6
#     year  lepsp  freq  rank quant abucat
#     <fct> <fct> <int> <int> <chr> <chr> 
#   1 1998  a        14     3 75    c     
#   2 1998  b        13     4 50    r     
#   3 1998  c         9     7 25    r     
#   4 1998  d        12     5 50    r     
#   5 1998  e        12     5 50    r     
#   6 1998  f         9     7 25    r     
#   7 1998  g        15     2 75    c     
#   8 1998  h        12     5 50    r     
#   9 1998  i        10     6 25    r     
#  10 1998  j        15     2 75    c     
#  # ... with 26 more rows
person jasbner    schedule 31.05.2018
comment
Спасибо за публикацию. По какой-то причине это не работает должным образом с моим фактическим набором данных. Я думаю, что проблема заключается в использовании аргумента max(). Я вижу в вашем выводе, что вы получили значения в пределах 25% процентиля, но при использовании кода в моем наборе данных значения, которые должны быть 25%, обозначаются как 50%. Я изменил аргумент на mutate(quant = c(0,25,50,75,100), что, казалось, исправило это. Однако у меня есть еще одна проблема... - person Danielle; 01.06.2018
comment
Когда я проверяю квантили для данного подмножества, кажется, что ваш код определяет значение freq как заданный квантиль только в том случае, если оно превышает максимальное значение, когда оно должно быть помечено как заданный квантиль относительно интервала между максимальным для 25 % и 50%, например. Например, если 75% = 12 и 100% = 15, то если значение freq равно 13, оно должно быть обозначено как 100%. Ваш код пометит это как 75%, потому что 13 не превышает 15. Я ценю любую информацию, которую вы можете дать. Я пробовал dput(), но у меня слишком большой набор данных. - person Danielle; 01.06.2018
comment
Я не уверен, что следую. В моем примере значения от 0 до 25% установлены на 25. Я сравниваю частоту с каждым из квантилей, и если частота больше, я беру это как назначенное ведро. Вот почему 100 было продублировано, потому что все смещено. Добавляя 0 в начале, вы сталкиваетесь с описанной вами проблемой, потому что в вашем примере нет ситуации, которая привела бы к 0. - person jasbner; 01.06.2018
comment
Но вы, вероятно, правы, что именно здесь могут возникнуть любые ошибки. Я проверю завтра утром, чтобы подтвердить, что мой код соответствует вашему засеянному примеру. - person jasbner; 01.06.2018
comment
@Danielle Я обновил свой код, чтобы включить ваши изменения. Дайте мне знать, если это не работает для вас. Надеюсь, case_when немного проще, чем предыдущие правки. - person jasbner; 01.06.2018