【问题标题】:Subset dataframe based on levels of a factor and create new variable of quantiles conditional on variable within subset基于因子水平的子集数据框,并根据子集中的变量创建新的分位数变量
【发布时间】:2018-05-31 19:19:21
【问题描述】:

我有一个像这样的数据框:

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

我想通过yeardf 进行子集化,并创建一个名为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)))

【问题讨论】:

  • 你如何计算你的量化值?
  • 首先我每年对sub1998sub1999 进行子集化,并使用quantile(sub1998$freq)quantile(sub1999$freq) 这样对于sub1998,如果freq 小于6 它= 25%,小于11 但大于 6 = 50% 小于 12.25 但大于 11= 75% 并且大于 12.25 = 100%
  • 那么为什么第二个 1998 freq 13 在你的输出中有一个 quant 是 50?
  • 拍摄,我忘了set.seed() ...我认为这是问题所在。我将编辑帖子,以便我的输出与原始 df 一致。
  • 如果您无法从头开始构建数据框,也可以使用dput 发布您的数据框

标签: r dataframe quantile


【解决方案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

【讨论】:

  • 感谢您的帖子。由于某种原因,这在我的实际数据集上无法正常工作。我认为问题在于可能使用max() 参数。我在您的输出中看到您的值在 25% 百分位数内,但是当在我的数据集上使用代码时,应该是 25% 的值被指定为 50%。我将参数更改为mutate(quant = c(0,25,50,75,100),这似乎可以解决这个问题。但是我还有一个问题...
  • 当我检查给定子集的分位数时,您的代码似乎将freq 值指定为给定分位数,前提是它超过了应标记为给定分位数的最大值例如,关于 25% 和 50% 的最大值之间的间隔。例如,如果 75% = 12 且 100%=15,那么如果 freq 值为 13,则应将其指定为 100%。您的代码会将其标记为 75%,因为 13 不超过 15。我感谢您提供的任何见解。我试过dput(),但我的数据集太大。
  • 我不确定我是否遵循。在我的示例中,0-25% 的值设置为 25。我将 freq 与每个分位数进行比较,如果 freq 较大,我将其作为指定的存储桶。这就是 100 被复制的原因,因为一切都被转移了。通过在开头添加 0,您会遇到您所描述的问题,因为从您的示例来看,没有任何情况会导致 0。
  • 但是您可能是对的,这是会发生任何错误的地方。明天早上我会检查以确认我的代码与您的种子示例匹配
  • @Danielle 我更新了我的代码以包含您的编辑。让我知道它是否不适合您。希望case_when 比之前的编辑更直接一些。
猜你喜欢
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
相关资源
最近更新 更多