Добавление столбца, который считает последовательные числа - PullRequest
0 голосов
/ 28 августа 2018

Я хотел бы добавить столбец, который подсчитывает количество последовательных значений. Большая часть того, что я вижу здесь, - это как посчитать повторяющиеся значения (1,1,1,1,1), и я бы хотел посчитать, когда число увеличивается на 1 (5,6,7,8,9) , Столбец ID - это то, что у меня есть, а столбец счетчика - это то, что я хотел бы создать. Спасибо!

ID Counter  
5  1  
6  2  
7  3  
8  4  
10 1  
11 2  
13 1  
14 2  
15 3  
16 4 

Ответы [ 5 ]

0 голосов
/ 28 августа 2018

Другое решение:

  breaks <- c(which(diff(ID)!=1), length(ID))
  x <- c(breaks[1], diff(breaks))
  unlist(sapply(x, seq_len))
0 голосов
/ 28 августа 2018

Этот использует исключительно высокоэффективную векторную арифметику. Идея такова:

1.берите накопленную сумму разностей ID

2. вычесть значение, если скачок больше единицы

cum <- c(0, cumsum(diff(ID)))  # take the cumulative difference of ID
ccm <- cum * c(1, (diff(ID) > 1))  # those with jump > 1 will remain its value

# subtract value with jump > 1 for all following numbers (see Link for reference)
# note: rep(0, n) is because ccm[...] starts at first non null value

counter <- cum - c(rep(0, which(diff(dat) != 1)[1]),
                   ccm[which(ccm != 0)][cumsum(ccm != 0)]) + 1
enter code here

Примечания

Это должно эффективно работать с вашими миллионами данных!

0 голосов
/ 28 августа 2018

Решение с использованием пакета dplyr. Идея состоит в том, чтобы вычислить разницу между каждым числом, чтобы создать столбец группировки, а затем назначить счетчик для каждой группы.

library(dplyr)

dat2 <- dat %>%
  mutate(Diff = ID - lag(ID, default = 0),
         Group = cumsum(Diff != 1)) %>%
  group_by(Group) %>%
  mutate(Counter = row_number()) %>%
  ungroup() %>%
  select(-Diff, -Group)
dat2
# # A tibble: 10 x 2
#       ID Counter
#    <int>   <int>
#  1     5       1
#  2     6       2
#  3     7       3
#  4     8       4
#  5    10       1
#  6    11       2
#  7    13       1
#  8    14       2
#  9    15       3
# 10    16       4

DATA

dat <- read.table(text = "ID
5   
6  
7  
8  
10  
11  
13  
14  
15  
16",
                  header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 28 августа 2018

Вы можете использовать

s=df$ID-shift(df$ID)
s[is.na(s)]=1   
ave(s,cumsum(s!=1),FUN=seq_along)
[1] 1 2 3 4 1 2 1 2 3 4
0 голосов
/ 28 августа 2018

Версия цикла проста:

for (i in 2:length(ID)) 
  if (diff(ID)[i-1] == 1) 
    counter[i] <- counter[i-1] +1
  else
    counter[i] <- 1

Но этот цикл будет работать очень плохо при n> 10 ^ 4! Я постараюсь придумать вектор-решение!

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