#r #dplyr
Вопрос:
У меня есть следующий сгенерированный df с возрастом и весом
df = data.frame( Age = sample(18:98, 1000, replace = TRUE), Weight = sample(80:250, 10000, replace = TRUE) )
Я хочу изменить непрерывные столбцы, создав сегменты на основе квантилей (25%, 50%, 75%. Это можно сделать так:
gt; quantile(df$Age, probs = c(0.25,0.5,0.75)) 25% 50% 75% 39 58 78
Однако я хочу использовать функцию cut, используя эти квантили (25%, 50%, 75%)
Как я могу это сделать? Я хочу, чтобы выходные данные преобразовывались во что-то подобное, где любая непрерывная переменная преобразуется в сегменты на основе квантиля (25%, 50%, 75%)
Age Weight (17.9,44.7] (137,193] (44.7,71.3] (137,193] (71.3,98.1] (79.8,137] (44.7,71.3] (193,250] (17.9,44.7] (79.8,137]
Комментарии:
1. (1) В вашем коде отсутствует запятая, пожалуйста, проверьте свой собственный код, прежде чем отправлять вопрос. (2) Пожалуйста, используйте
set.seed
, прежде чем использовать случайные числа, чтобы мы могли попытаться воспроизвести ваши случайные числа (мы не можем). (3) Учитывая , что выAge
должны быть помещены в корзину39,58,78
, откуда берутся ожидаемые диапазоныAge
?2. Если вам нужно что-то более мощное , чем просто использование вывода
quantile
incut
, взгляните наclassInt
пакет, в котором есть функцияclassIntervals
, которая разбивает непрерывные переменные на ячейки на основе одной из нескольких различных функций.
Ответ №1:
Просто передайте свои квантили в качестве второго аргумента cut
, хотя добавьте квантили 0 и 1 , чтобы ваши сокращения имели нижнюю и верхнюю границы. (т. Е. c(0, 0.25, 0.5, 0.75, 1)
, которые можно кратко записать как 0:4 / 4
)
Версия Tidyverse
library(dplyr) as_tibble(df) %gt;% mutate(across(everything(), .fn = function(x) cut(x, quantile(x, 0:4/4)))) #gt; # A tibble: 10,000 x 2 #gt; Age Weight #gt; lt;fctgt; lt;fctgt; #gt; 1 (18,38] (80,121] #gt; 2 (78,98] (121,165] #gt; 3 (18,38] (121,165] #gt; 4 (58,78] (208,250] #gt; 5 (58,78] (165,208] #gt; 6 (78,98] (80,121] #gt; 7 (38,58] (165,208] #gt; 8 (58,78] (80,121] #gt; 9 (38,58] (165,208] #gt; 10 (58,78] (121,165] #gt; # ... with 9,990 more rows
Базовая версия R
df$Age lt;- cut(df$Age, quantile(df$Age, 0:4/4)) df$Weight lt;- cut(df$Weight, quantile(df$Weight, 0:4/4))
Комментарии:
1. Привет, я на самом деле хочу сделать квантили (0,25, 0,5, 0,75), но когда я это делаю
df %gt;% mutate(across(everything(), .fn = function(x) cut(x, quantile(x, probs = c(0.25,0.5,0.75)))))
, я получаю значения lt;NAgt;. Вы знаете, почему это так? Кроме того, я вообще не хочу мутировать во всем, потому что я хочу обобщить, чтобы фрейм данных мог иметь не все непрерывные значения.2. @Eisen если ваш самый низкий разрыв составляет 25% квантиля, то все, что ниже этого, не будет включено и станет
NA
. Аналогично, все, что превышает 75% — ный центиль, будетNA
, если вы установите эти разрывы. Вот почему я предложил добавить 0 и 1 центиль — это разделит ваши данные на 4 правильных квантиля, не исключая самый высокий и самый низкий квартили. Например, квантиль 0-25%, квартиль 25-50%, квартиль 50-75% и квартиль 75-100%3. @Eisen смотрите мое обновление, чтобы сделать это для каждого столбца в базе R
4. Это круто, но не совсем то, чего я хочу.
quantile(df$Age, probs = c(0.25,0.5,0.75))
бы выделить нужный мне пользовательский квантиль.. Пытаюсь понять, как включить его вcut()
себя . Таким образом, все, что составляет 25% или меньше, считается 25%, а все, что составляет 75% или больше, считается 75%5. @Eisen если вы хотите, чтобы каждое наблюдение было помещено в корзину, самые низкие и самые высокие значения наблюдения должны находиться в пределах самого высокого и самого низкого значения
breaks
. Ввод ваших квантилей сохранит только второй и четвертый квантили. Это то, чего ты хочешь? Если нет, не могли бы вы объяснить, чего вы пытаетесь достичь немного более подробно? Спасибо
Ответ №2:
В моей santoku
посылке есть chop_quantiles()
:
library(santoku) df[] lt;- apply(df, 2, chop_quantiles, 0:4/4)
или еще проще:
df[] lt;- apply(df, 2, chop_equally, 4)
Пустые скобки-это трюк, который сохраняется df
как data.frame.
Если вам нужны исходные значения в ваших метках, вы можете сделать:
df[] lt;- apply(df, 2, chop_equally, 4, labels = lbl_intervals(raw = TRUE))