varias superponer studio nuevo lineas graficos graficas definicion data crear como r dataframe r-faq

superponer - Numeración de filas dentro de grupos en un marco de datos



superponer graficas en r (5)

Trabajando con un marco de datos similar a esto:

set.seed(100) df <- data.frame(cat = c(rep("aaa", 5), rep("bbb", 5), rep("ccc", 5)), val = runif(15)) df <- df[order(df$cat, df$val), ] df cat val 1 aaa 0.05638315 2 aaa 0.25767250 3 aaa 0.30776611 4 aaa 0.46854928 5 aaa 0.55232243 6 bbb 0.17026205 7 bbb 0.37032054 8 bbb 0.48377074 9 bbb 0.54655860 10 bbb 0.81240262 11 ccc 0.28035384 12 ccc 0.39848790 13 ccc 0.62499648 14 ccc 0.76255108 15 ccc 0.88216552

Estoy tratando de agregar una columna con numeración dentro de cada grupo. Hacerlo de esta manera obviamente no está usando los poderes de R:

df$num <- 1 for (i in 2:(length(df[,1]))) { if (df[i,"cat"]==df[(i-1),"cat"]) { df[i,"num"]<-df[i-1,"num"]+1 } } df cat val num 1 aaa 0.05638315 1 2 aaa 0.25767250 2 3 aaa 0.30776611 3 4 aaa 0.46854928 4 5 aaa 0.55232243 5 6 bbb 0.17026205 1 7 bbb 0.37032054 2 8 bbb 0.48377074 3 9 bbb 0.54655860 4 10 bbb 0.81240262 5 11 ccc 0.28035384 1 12 ccc 0.39848790 2 13 ccc 0.62499648 3 14 ccc 0.76255108 4 15 ccc 0.88216552 5

¿Cuál sería una buena manera de hacer esto?


Aquí hay otra forma de hacerlo usando dplyr :

library(dplyr) df %>% group_by(cat) %>% mutate(num = 1:n())


Aquí hay una opción que usa un ciclo for por grupos más bien por filas (como lo hizo OP)

for (i in unique(df$cat)) df$num[df$cat == i] <- seq_len(sum(df$cat == i))


Me gustaría agregar una variante de data.table utilizando la función rank() , que ofrece la posibilidad adicional de cambiar el orden y lo hace un poco más flexible que la solución seq_len() y es bastante similar a las funciones row_number en RDBMS.

# Variant with ascending ordering library(data.table) dt <- data.table(df) dt[, .( val , num = rank(val)) , by = list(cat)][order(cat, num),] cat val num 1: aaa 0.05638315 1 2: aaa 0.25767250 2 3: aaa 0.30776611 3 4: aaa 0.46854928 4 5: aaa 0.55232243 5 6: bbb 0.17026205 1 7: bbb 0.37032054 2 8: bbb 0.48377074 3 9: bbb 0.54655860 4 10: bbb 0.81240262 5 11: ccc 0.28035384 1 12: ccc 0.39848790 2 13: ccc 0.62499648 3 14: ccc 0.76255108 4 # Variant with descending ordering dt[, .( val , num = rank(val)) , by = list(cat)][order(cat, num),]


Para hacer que esta pregunta de r-faq más completa, una alternativa de base R con sequence y rle :

df$num <- sequence(rle(df$cat)$lengths)

que da el resultado esperado:

> df cat val num 4 aaa 0.05638315 1 2 aaa 0.25767250 2 1 aaa 0.30776611 3 5 aaa 0.46854928 4 3 aaa 0.55232243 5 10 bbb 0.17026205 1 8 bbb 0.37032054 2 6 bbb 0.48377074 3 9 bbb 0.54655860 4 7 bbb 0.81240262 5 13 ccc 0.28035384 1 14 ccc 0.39848790 2 11 ccc 0.62499648 3 15 ccc 0.76255108 4 12 ccc 0.88216552 5

Si df$cat es una variable de factor, primero debe envolverlo como as.character .

df$num <- sequence(rle(as.character(df$cat))$lengths)


Utilice ave , ddply , dplyr o data.table :

df$num <- ave(df$val, df$cat, FUN = seq_along)

o:

library(plyr) ddply(df, .(cat), mutate, id = seq_along(val))

o:

library(dplyr) df %>% group_by(cat) %>% mutate(id = row_number())

o (la memoria más eficiente, como se asigna por referencia dentro de DT ):

library(data.table) DT <- data.table(df) DT[, id := seq_len(.N), by = cat] DT[, id := rowid(cat)]