【问题标题】:Assigning values in a column to deciles when breaks are not unique当中断不唯一时,将列中的值分配给十分位数
【发布时间】:2018-12-21 14:23:45
【问题描述】:

假设我有一个包含 1000 个数字的向量。我想获得这个向量的十分位数,然后找到每个十分位数的平均值。但是,此向量中有 215+ 个零。这意味着第一次和第二次休息将为零,因此我会遇到Cut() error - 'breaks' are not unique 错误。我想要的是为第一个十分位分配 100 个零,为第二个十分位分配另外 100 个零,为第三个十分位分配最后 15 个零。这样第一个和第二个十分位数的平均值将为零。这是一个具有类似问题的可重现且较小的示例:

v=c(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 5, 6, 3, 7)
cut_q10 <- quantile(v, probs = seq(0, 1, 0.1))
v_q10 =cut(v, breaks = cut_q10,labels = FALSE)
#Error in cut.default(v, breaks = cut_q10, labels = FALSE) : 
#  'breaks' are not unique

我想得到的是:

v_q10 = c(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,10,9,10)

v_q10 = c(2,2,1,1,3,4,4,3,5,5,6,6,7,7,8,8,9,10,9,10)

等等... 只要第一个十分位数中有两个 0,第二个十分位数中有两个 0,第三个中有两个 1,第四个中有两个 1 等等,所有这些都是可以接受的,这样无论哪个v_q10 在我获得找到我达到的每个十分位数的方法:

merged = as.data.frame(cbind(v,v_q10))
merged = merged%>%group_by(v_q10)%>%summarise(means = mean(v))

   v_q10 means
#   <dbl> <dbl>
# 1     1   0  
# 2     2   0  
# 3     3   1  
# 4     4   1  
# 5     5   1  
# 6     6   2  
# 7     7   2  
# 8     8   3  
# 9     9   4  
#10    10   6.5

我知道可以通过编写很长的代码来实现这一点,但我想知道是否有一个函数或几行代码可以实现这一点。 提前致谢。

【问题讨论】:

  • 你试过dplyr::ntile吗?

标签: r quantile


【解决方案1】:

试试这个:

cut(rank(v, ties = "first"), 10, lab = FALSE)
## [1]  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9 10  9 10

替代方法包括使用ties = "last" 或使用ties = "random" 或使用order(order(v)) 代替rank(...)

【讨论】:

  • 非常感谢,这很好用。我还想知道一件事。如果我没有明确给出向量 v 而是作为每个值的数据框及其旁边的权重,我可以做同样的事情,如:`v = data.frame(values=c(0,1,2 ,3,5,6,7),weights=c(4,6,4,3,1,1,1))
  • 如果按重量计算,您的意思是该值要重复该次数,那么第一种形式:v &lt;- with(DF, rep(values, weights))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多