Создайте столбец из groupby с рассчитанной меткой

У меня есть фрейм данных, и я хотел бы создать столбец фрейма данных на основе groupby в другом столбце. Группировать по столбцу следует с шагом 50, а метка должна быть средним числом в номерах групп. Я демонстрирую это здесь на воспроизводимом примере.

Вот фрейм данных

das <- data.frame(val=1:27,
              weigh=c(20,25,37,38,50,52,56,59,64,68,69,70,75,76,82,85,90,100,109,150,161,178,181,179,180,201,201))

    val  weigh
1     1  20
2     2  25
3     3  37
4     4  38
5     5  50
6     6  52
7     7  56
8     8  59
9     9  64
10   10  68
11   11  69
12   12  70
13   13  75
14   14  76
15   15  82
16   16  85
17   17  90
18   18 100
19   19 109
20   20 150
21   21 161
22   22 178
23   23 181
24   24 179
25   25 180
26   26 201
27   27 201

Желаемый результат будет

    val  weigh label
1     1  20    45
2     2  25    45
3     3  37    45
4     4  38    45
5     5  50    45
6     6  52    45
7     7  56    45
8     8  59    45
9     9  64    45
10   10  68    45
11   11  69    45
12   12  70    45
13   13  75    95
14   14  76    95
15   15  82    95
16   16  85    95
17   17  90    95
18   18 100    95
19   19 109    95
20   20 150    145
21   21 161    145
22   22 178    195
23   23 181    195
24   24 179    195
25   25 180    195
26   26 201    195
27   27 201    195

Здесь 45 вычисляется как 20+ (20 + 50) / 2 = 45, где 20 - это место, где оно начинается, а 20 + 50 = 70 - это место, где этой группе нужно остановиться. А метка - это среднее число от 20 до 70, то есть 45.

Аналогично с другими лейблами

 70+(70+50)/2= 95
 120 + (170)/2= 145
 170 + (220)/2 = 195

Я новичок в R и пробовал посмотреть здесь множество источников, но не смог найти ничего, что могло бы делать что-то подобное. Самое близкое, что я смог найти, - это группировка с помощью cut2

df %>% mutate(label = as.numeric(cut2(weigh, g=5))) 
2
0
129
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
library(dplyr)

# create your breaks
breaks = unique(c(seq(min(das$weigh), max(das$weigh)+1, 50), max(das$weigh)+1))

das %>%
  group_by(group = cut(weigh, breaks, right=F)) %>%        # group by intervals
  mutate(group2 = as.numeric(group),                       # use the intervals as a number
         label = (breaks[group2]+breaks[group2]+50)/2) %>% # call the corresponding break value and calculate your label
  ungroup()

# # A tibble: 27 x 5
#     val weigh group   group2 label
#   <int> <dbl> <fct>    <dbl> <dbl>
# 1     1    20 [20,70)      1    45
# 2     2    25 [20,70)      1    45
# 3     3    37 [20,70)      1    45
# 4     4    38 [20,70)      1    45
# 5     5    50 [20,70)      1    45
# 6     6    52 [20,70)      1    45
# 7     7    56 [20,70)      1    45
# 8     8    59 [20,70)      1    45
# 9     9    64 [20,70)      1    45
#10    10    68 [20,70)      1    45
# # ... with 17 more rows

Вы можете удалить ненужные столбцы. Я оставил их там, чтобы было легче понять, как работает процесс.

Именно то, что я ищу. Спасибо

user10316615 14.09.2018 11:25

Другие вопросы по теме