Crear contador con múltiples variables

Tengo mis datos que se muestran a continuación:

CustomerID TripDate 1 1/3/2013 1 1/4/2013 1 1/9/2013 2 2/1/2013 2 2/4/2013 3 1/2/2013 

Necesito crear una variable de contador, que será como a continuación:

 CustomerID TripDate TripCounter 1 1/3/2013 1 1 1/4/2013 2 1 1/9/2013 3 2 2/1/2013 1 2 2/4/2013 2 3 1/2/2013 1 

Tripcounter será para cada cliente.

Usa ave . Suponiendo que su data.frame se llama “mydf”:

 mydf$counter <- with(mydf, ave(CustomerID, CustomerID, FUN = seq_along)) mydf # CustomerID TripDate counter # 1 1 1/3/2013 1 # 2 1 1/4/2013 2 # 3 1 1/9/2013 3 # 4 2 2/1/2013 1 # 5 2 2/4/2013 2 # 6 3 1/2/2013 1 

Por lo que vale, también implementé una versión de este enfoque en una función incluida en mi paquete "splitstackshape". La función se llama getanID :

 mydf <- data.frame(IDA = c("a", "a", "a", "b", "b", "b", "b"), IDB = c(1, 2, 1, 1, 2, 2, 2), values = 1:7) mydf # install.packages("splitstackshape") library(splitstackshape) # getanID(mydf, id.vars = c("IDA", "IDB")) getanID(mydf, id.vars = 1:2) # IDA IDB values .id # 1 a 1 1 1 # 2 a 2 2 1 # 3 a 1 3 2 # 4 b 1 4 1 # 5 b 2 5 1 # 6 b 2 6 2 # 7 b 2 7 3 

Como puede ver en el ejemplo anterior, escribí la función de tal manera que puede especificar una o más columnas que deben tratarse como columnas de ID. Comprueba si alguno de los id.vars está duplicado, y si lo está, genera una nueva variable de identificación para ti.

También puede usar plyr para esto (usando los datos de ejemplo de @AnadaMahto):

 > ddply(mydf, .(IDA), transform, .id = seq_along(IDA)) IDA IDB values .id 1 a 1 1 1 2 a 2 2 2 3 a 1 3 3 4 b 1 4 1 5 b 2 5 2 6 b 2 6 3 7 b 2 7 4 

o incluso:

 > ddply(mydf, .(IDA, IDB), transform, .id = seq_along(IDA)) IDA IDB values .id 1 a 1 1 1 2 a 1 3 2 3 a 2 2 1 4 b 1 4 1 5 b 2 5 1 6 b 2 6 2 7 b 2 7 3 

Tenga en cuenta que plyr no tiene la reputación de ser la solución más rápida, por lo que debe echarle un vistazo a data.table .


Aquí hay un enfoque de data.table :

 library(data.table) DT <- data.table(mydf) DT[, .id := sequence(.N), by = "IDA,IDB"] DT # IDA IDB values .id # 1: a 1 1 1 # 2: a 2 2 1 # 3: a 1 3 2 # 4: b 1 4 1 # 5: b 2 5 1 # 6: b 2 6 2 # 7: b 2 7 3 

Mientras tanto, también puedes usar dplyr . si su data.frame se llama mydata

 library(dplyr) mydata %>% group_by(CustomerID) %>% mutate(TripCounter = row_number()) 

Necesito hacer esto a menudo, y escribí una función que lo lleva a cabo de manera diferente a las respuestas anteriores. No estoy seguro de qué solución es más eficiente.

 idCounter <- function(x) { unlist(lapply(rle(x)$lengths, seq_len)) } mydf$TripCounter <- idCounter(mydf$CustomerID) 

Aquí está el código de estilo de procedimiento. No creo en cosas como si estás usando loop en R entonces probablemente estés haciendo algo mal

 x <- dataframe$CustomerID dataframe$counter <- 0 y <- dataframe$counter count <- 1 for (i in 1:length(x)) { ifelse (x[i] == x[i-1], count <- count + 1, count <- 1 ) y[i] <- count } dataframe$counter <- y 

Esta no es la respuesta correcta, pero muestra algunas cosas interesantes en comparación con los ciclos for, la vectorización es rápida y no le importa la actualización secuencial. a <-read.table (textConnection ("CustomerID TripDate 1 1/3/2013 1 1/4/2013 1 1/9/2013 2 2/1/2013 2 2/4/2013 3 1/2/2013") , encabezado = VERDADERO)

 a <- a %>% group_by(CustomerID,TripDate) # must in order res <- rep(1, nrow(a)) #base @ 1 res[2:6] <-sapply(2:6, function(i)if(a$CustomerID[i]== a$CustomerID[i - 1]) {res[i] = res[i-1]+1} else {res[i]= res[i]}) a$TripeCounter <- res 
    Intereting Posts