разрезать переменную на куски в R - PullRequest
1 голос
/ 22 октября 2019

Я пытаюсь cut() мои данные D на 3 части: [0-4], [5-12], [13-40] ( см. Рис. Ниже ). Но мне интересно, как точно определить мои breaks в cut для достижения этого?

Вот мои данные и код R:

D <- read.csv("https://raw.githubusercontent.com/rnorouzian/m/master/t.csv", h = T)


 table(cut(D$time, breaks = c(0, 5, 9, 12))) ## what should breaks be?

 # (0,5]  (5,9] (9,12]  # cuts not how I want the 3 pieces .
 #  228     37     10

enter image description here

Ответы [ 4 ]

2 голосов
/ 22 октября 2019

Вы должны добавить два дополнительных аргумента right и include.lowest к своему коду!

table(cut(D$time, breaks = c(0, 5, 13, 40), right=FALSE, include.lowest = TRUE)) 

В случае right=FALSE интервалы должны быть закрыты слева и открыты справа, напримерчто вы получите желаемый результат. include.lowest=TRUE означает, что ваше максимальное значение разрыва (здесь 40) включено в последний интервал. Результат:

[0,5)  [5,13) [13,40] 
 319      47      20

Наоборот, вы можете написать:

table(cut(D$time, breaks = c(0, 4, 12, 40), right=TRUE, include.lowest = TRUE)) 

с результатом:

 [0,4]  (4,12] (12,40] 
  319      47      20 

Оба означают то, что вы ищете:

[0,4]  [5,12] [13,40] 
 319      47      20
2 голосов
/ 22 октября 2019

Это дает правильные сегменты, но для обозначения интервала потребуется настройка. Предполагая, что все времена являются целыми числами. Возможно, потребуется настроить метки вручную - каждый раз, когда у вас есть нотация с открытым открытым интервалом, замените метку фактора нотацией с закрытым интервалом. Используйте вашу лучшую строку 'magic'

Лично я хотел бы убедиться, что все возможности покрыты. Возможно, будущие данные этого процесса могут превысить 40? Мне нравится ставить верхнюю границу +Inf во всех моих разрезах. Это предотвращает проникновение NA в данные.

Что нужно cut, так это опция "только целые числа".

F=cut(D$time,c(0,5,13,40),include.lowest = TRUE,right=FALSE)
# the below levels hard coded but you could write a loop to turn all labels
# of the form [m,n) into [m,n-1]
levels(F)[1:2]=c('[0,4]','[5,12]')

Как правило, перед окончательными результатами требуется больше анализа. получилось, так что я бы не стал слишком потеть на ярлыках, пока работа не приблизилась к завершению.

Вот мои результаты

 > table(F) 
 F
 [0,4]  [5,12]  [13,40] 
 319      47      20 
2 голосов
/ 22 октября 2019

Обозначение (a, b] означает «> a и <= b». </p>

Итак, чтобы получить желаемый результат, просто определите срезы, чтобы получить желаемую группировку, включая более низкуюи верхняя граница:

table(cut(D$time, breaks=c(-1, 4, 12, 40)))

## (-1,4]  (4,12] (12,40] 
##   319      47      20 

Вам также может быть полезно взглянуть на два аргумента right=FALSE, который изменяет конечные точки интервалов с (a,b] на [a,b) и include.lowest,который включает в себя самое низкое значение breaks (в примере OP это [0,5] с закрытыми скобками на нижней границе). Вы также можете использовать бесконечность. Вот пример с парой из этих опций, которые будут использоваться:

table(cut(D$time, breaks = c(-Inf, 4, 12, Inf), include.lowest=TRUE))

## [-Inf,4]    (4,12] (12, Inf] 
##     319        47        20 
1 голос
/ 22 октября 2019

R может сравнивать целые числа с числами с плавающей точкой, как в

> 6L >= 8.5
[1] FALSE

Таким образом, вы можете использовать числа с плавающей точкой как breaks в разрезе, например, в

table(cut(D$time, breaks = c(-.5, 4.5, 12.5, 40.5)))

Для целых чисел это заполняет ваше ведроопределение [0-4], [5-12], [13-40] без необходимости много думать о квадратных скобках против круглых скобок.

Причудливая альтернатива - кластеризация вокруг средних значений ваших корзин, как в

D <- read.csv("https://raw.githubusercontent.com/rnorouzian/m/master/t.csv", h = T)
D$cluster <- kmeans(D$time, center = c(4/2, (5+12)/2, (13+40)/2))$cluster
plot(D$time, rnorm(nrow(D)), col=D$cluster)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...