Присвояване на стойности в колона на децили, когато прекъсванията не са уникални

Да приемем, че имам вектор с 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)

or

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

и т.н... Всички те са приемливи, стига да има две нули в първия децил, две нули във втория, две 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

Знам, че е възможно да се постигне това чрез писане на дълъг код, но се чудех дали има функция или код от няколко реда, който може да постигне това. Благодаря предварително.


person Elif Cansu Akoğuz    schedule 21.12.2018    source източник
comment
Опитвали ли сте dplyr::ntile?   -  person tomaz    schedule 21.12.2018


Отговори (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(...).

person G. Grothendieck    schedule 21.12.2018
comment
благодаря много, това работи чудесно. Чудех се още нещо. Мога ли да направя същото нещо, ако не ми беше даден векторът v изрично, а като рамка от данни на всяка стойност и нейното тегло до нея, както в: `v = data.frame(values=c(0,1,2) ,3,5,6,7),тегла=c(4,6,4,3,1,1,1)) - person Elif Cansu Akoğuz; 21.12.2018
comment
Ако под тегло имате предвид, че тази стойност трябва да се повтори този брой пъти, тогава първата форма: v <- with(DF, rep(values, weights)) - person G. Grothendieck; 21.12.2018