Добавить счетчик группы во фрейм данных на основе столбца

Скажем, у меня есть отсортированный фрейм данных с переменной расстояния d, указывающей расстояние между мерами в переменной a.

library(dplyr)
set.seed(1)
df <- 
  data.frame(a=sort(sample(2:20,8))) %>% 
  mutate(d = a-lag(a))

Это дает:

> df
   a  d
1  5 NA
2  7  2
3  8  1
4  9  1
5 11  2
6 14  3
7 15  1
8 16  1

Я пытаюсь добавить некоторую переменную счетчика / группировки g, которая указывает, больше ли d, чем, скажем, 2. g может принимать такие значения, как: g1, g2, ... и т. Д. Другими словами, я хотел бы "увеличить" g когда d> 2. В данных ниже мы получим:

>df a   d   g
1   5   NA  g1
2   7   2   g1
3   8   1   g1
4   9   1   g1
5   11  2   g1
6   14  3   g2
7   15  1   g2
8   16  1   g2

Я решил использовать функцию с глобальным побочным эффектом (и да, это вообще плохая идея, я не мог придумать ничего другого):

f <- function(x){
  if(x)
    g <<- g +1
  return(paste0('g', g))
}

А затем сделайте:

g=0
df %>% 
  mutate(g = ifelse(is.na(d)|d>2, f(T), f(F)))

Но g не увеличивается в mutate (или sapply). В реальных данных у меня может быть тысячи g групп.


person user3375672    schedule 24.08.2017    source источник


Ответы (2)


Ты можешь попробовать,

with(df, paste0('g', cumsum(replace(d, is.na(d), 0) > 2)+1))
#[1] "g1" "g1" "g1" "g1" "g1" "g2" "g2" "g2"
person Sotos    schedule 24.08.2017

Решение с использованием dplyr и data.table. df2 - окончательный результат.

library(dplyr)
library(data.table)

df2 <- df %>%
  mutate(Large2 = ifelse(d > 2, 1, NA)) %>%
  mutate(RunID = rleid(Large2)) %>%
  mutate(ID = ifelse(RunID %% 2 == 0, RunID + 1, RunID)) %>%
  mutate(g = paste0("g", group_indices(., ID))) %>%
  select(a, d, g)
person www    schedule 24.08.2017