Доступно ли объединение в стиле cut () в dplyr?

Есть ли способ сделать что-то вроде функции cut() для объединения числовых значений в dplyr таблицу? Я работаю над большой таблицей postgres и в настоящее время могу либо написать оператор case в sql с самого начала, либо вывести неагрегированные данные и применить cut(). У обоих есть довольно очевидные недостатки ... операторы case не особенно элегантны, а извлечение большого количества записей через collect() совсем неэффективно.


person Michael Williams    schedule 11.02.2014    source источник
comment
Пока нет, но это в списке дел.   -  person hadley    schedule 12.02.2014
comment
Думаю, @hadley имеет в виду нечто большее, но это работает: BOD %.% group_by(cut(Time, 2)) %.% summarise(mean = mean(demand))   -  person G. Grothendieck    schedule 12.02.2014
comment
Связанный: stackoverflow.com/questions/35204157/   -  person Berk U.    schedule 08.02.2016
comment
Думаю, я ответил на это здесь в ответ на Berk U. stackoverflow.com/questions/35204157/   -  person sean    schedule 15.08.2016


Ответы (3)


Чтобы получить немедленный ответ для других, прибывающих сюда через поисковую систему, форма n-разрывов cut теперь реализована как функция ntile в dplyr:

> data.frame(x = c(5, 1, 3, 2, 2, 3)) %>% mutate(bin = ntile(x, 2))
  x bin
1 5   2
2 1   1
3 3   2
4 2   1
5 2   1
6 3   2
person drhagen    schedule 12.05.2016
comment
Что есть NA в разделенных столбцах? - person vagabond; 01.11.2016
comment
@vagabond возвращает NA. Посмотрите пример на ntile странице документации. - person sinQueso; 26.05.2017
comment
Строго говоря, это не общая cut() функция для произвольных разрывов, это только для ntiles (приблизительный ранг, который разбивает входной вектор на «n» сегментов) - person smci; 07.08.2018

Я вижу, что этот вопрос никогда не обновлялся с помощью решения tidyverse, поэтому я добавлю его для потомков.

Используемая функция - cut_interval из пакета ggplot2. По моему опыту, она работает аналогично base::cut, но лучше справляется с маркировкой начальной и конечной точек, чем функция base, потому что cut увеличивает диапазон на 0,1% на каждом конце.

data.frame(x = c(5, 1, 3, 2, 2, 3)) %>% mutate(bin = cut_interval(x, n = 2))
  x   bin
1 5 (3,5]
2 1 [1,3]
3 3 [1,3]
4 2 [1,3]
5 2 [1,3]
6 3 [1,3]

Вы также можете указать ширину бункера с помощью cut_width.

data.frame(x = c(5, 1, 3, 2, 2, 3)) %>% mutate(bin = cut_width(x, width = 2, center = 1))
  x   bin
1 5 (4,6]
2 1 [0,2]
3 3 (2,4]
4 2 [0,2]
5 2 [0,2]
6 3 (2,4]
person hmhensen    schedule 18.09.2020

Следующее работает с dplyr, если x - это переменная, которую мы хотим сохранить:

# Make n bins
df %>% mutate( x_bins = cut( x, breaks = n )

# Or make specific bins
df %>% mutate( x_bins = cut( x, breaks = c(0,2,6,10) )
person al_the_man    schedule 24.06.2020