2015-10-06 3 views
-1

У меня есть большой data.frame, который я хочу сгенерировать новый столбец (называемый Seq), который имеет последовательные значения, которые перезапускаются каждый раз, когда происходит изменение в другом столбце. Ниже приведен пример data.frame (с опущенными столбцами) и новый столбец Seq. Как вы можете видеть, есть подсчет секвенций, но каждый раз, когда появляется новый IDPath, число секвестров перезапускается. Длина sequentiel может иметь различную длину, некоторые из них 1 длинный, в то время как другие 300.Числовая последовательность с условием

IDPath LogTime    Seq 
AADS  19-06-2015 01:57  1 
AADS  19-06-2015 01:55  2 
AADS  19-06-2015 01:54  3 
AADS  19-06-2015 01:53  4 
DHSD  19-06-2015 12:57  1 
DHSD  19-06-2015 10:58  2 
DHSD  19-06-2015 09:08  3 
DHSD  19-06-2015 08:41  4 
+1

Это все великие ответы! Спасибо за помощь! Все они решают мою проблему, спасибо! – KhalidN

+0

Прохладный. Вы должны выбрать один и принять его в качестве ответа (prbly Japp или CathG, если вы используете data.table). – hrbrmstr

+3

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

ответ

3

Обязательный Hadleyverse ответ (основание R ответ также включены после Hadleyvese ответа):

library(dplyr) 

dat <- read.table(text="IDPath LogTime 
AADS  '19-06-2015 01:57'  
AADS  '19-06-2015 01:55'  
AADS  '19-06-2015 01:54'  
AADS  '19-06-2015 01:53'  
DHSD  '19-06-2015 12:57'  
DHSD  '19-06-2015 10:58'  
DHSD  '19-06-2015 09:08'  
DHSD  '19-06-2015 08:41'  ", header=TRUE, stringsAsFactors=FALSE, quote="'") 

mutate(group_by(dat, IDPath), Seq=1:n()) 

ИЛИ (через Дэвида Arenburg)

mutate(group_by(dat, IDPath), Seq=row_number()) 

Или, если вы в трубопровод:

dat %>% 
    group_by(IDPath) %>% 
    mutate(Seq=1:n()) 

ИЛИ (через David Arenburg)

dat %>% 
    group_by(IDPath) %>% 
    mutate(Seq=row_number()) 

обязательное основание R ответ:

unsplit(lapply(split(dat, dat$IDPath), transform, Seq=1:length(IDPath)), dat$IDPath) 

ИЛИ более идиоматически (через Дэвида снова)

with(dat, ave(IDPath, IDPath, FUN = seq_along)) 

Если это действительно ОГРОМНАЯ кадр данных, то вы можете начать с tbl_dt(dat) для dplyr решений, но CathG-й или версия Яапа будет быстрее, если вы уже используете data.table.

+0

или 'row_number()' –

+0

thx. добавлено (вместе с базовым R-решением) – hrbrmstr

+0

Я думаю, что idimatic base будет чем-то вроде 'с (dat, ave (IDPath, IDPath, FUN = seq_along))' –

5

Использование data.table пакета, вот способ получить то, что вы хотите:

require(data.table) 
setDT(dt)[, Seq:=1:.N, by=IDPath] 
# or, as mentioned by @DavidArenburg 
setDT(dt)[, Seq:=seq_len(.N), by=IDPath] 

dt 
# IDPath   LogTime Seq 
#1: AADS 19-06-2015 01:57 1 
#2: AADS 19-06-2015 01:55 2 
#3: AADS 19-06-2015 01:54 3 
#4: AADS 19-06-2015 01:53 4 
#5: DHSD 19-06-2015 12:57 1 
#6: DHSD 19-06-2015 10:58 2 
#7: DHSD 19-06-2015 09:08 3 
#8: DHSD 19-06-2015 08:41 4 
+1

'seq_len (.N)' будет, вероятно, немного быстрее, чем ':' –

4

Вы также можете использовать функцию rleid из data.table пакета, который специально предназначен для создания столбца типа идентификационного прогона длиной в группировке операций:

library(data.table) 
setDT(df)[, Seq:=rleid(LogTime), by=IDPath] 

Результат:

> df 
    IDPath   LogTime Seq 
1: AADS 19-06-2015:01:57 1 
2: AADS 19-06-2015:01:55 2 
3: AADS 19-06-2015:01:54 3 
4: AADS 19-06-2015:01:53 4 
5: DHSD 19-06-2015:12:57 1 
6: DHSD 19-06-2015:10:58 2 
7: DHSD 19-06-2015:09:08 3 
8: DHSD 19-06-2015:08:41 4 

других вариантом было бы использовать новую функцию rowid, введенную в the current development version:

setDT(df)[, Seq:=rowid(IDPath)] 
1

Это может быть немного длительный подход, но это просто,

alphabets <- c("a", "a", "b", "c", "c") 
df <- data.frame(alphabets) 
a <- table(df$alphabets) 
k <- 1 


for (i in 1:length(a)) 
{ 
l <- 1 
for(j in 1:a[i]) 
{ 
    df$seq[k] <- l 
    k <- k+ 1 
    l <- l+ 1 
} 
} 

df 
# alphabets seq 
#1   a 1 
#2   a 2 
#3   b 1 
#4   c 1 
#5   c 2