seleccionar - Cuadro de datos del subconjunto basado en el número de filas por grupo
filtrar datos en r (2)
Primero, dos alternativas de base
. Uno se basa en la table
, y el otro en ave
y length
. Entonces, dos maneras data.table
.
1. table
tt <- table(df$name)
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
Si quieres recorrerlo paso a paso:
# count each ''name'', assign result to an object ''tt''
tt <- table(df$name)
# which ''name'' in ''tt'' occur more than three times?
# Result is a logical vector that can be used to subset the table ''tt''
tt < 3
# from the table, select ''name'' that occur < 3 times
tt[tt < 3]
# ...their names
names(tt[tt < 3])
# rows of ''name'' in the data frame that matches "the < 3 names"
# the result is a logical vector that can be used to subset the data frame ''df''
df$name %in% names(tt[tt < 3])
# subset data frame by a logical vector
# ''TRUE'' rows are kept, ''FALSE'' rows are removed.
# assign the result to a data frame with a new name
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
2. ave
y length
Según lo sugerido por @flodel:
df[ave(df$x, df$name, FUN = length) < 3, ]
3. data.table
: .N
y .SD
:
library(data.table)
setDT(df)[, if (.N < 3) .SD, by = name]
4. data.table
: .N
y .I
:
setDT(df)
df[df[, .I[.N < 3], name]$V1]
Al evitar llamar a [.data.table
para cada grupo, esta alternativa sería más rápida. Ver, por ejemplo, aquí: Subconjunto por grupo con data.table .
Consulte también el número de observaciones / filas del recuento de preguntas y respuestas relacionado por grupo y agregue el resultado al marco de datos .
Tengo datos como este, donde algunos "nombres" ocurren más de 3 veces:
df <- data.frame(name = c("a", "a", "a", "b", "b", "c", "c", "c", "c"), x = 1:9)
Deseo subconjuntar (filtrar) los datos según el número de filas (observaciones) dentro de cada nivel de la variable "nombre". Si un cierto nivel de "nombre" ocurre más de 3 veces, quiero eliminar todas las filas que pertenecen a ese nivel.
Escribí este código, pero no puedo hacerlo funcionar.
as.data.frame(table(unique(df)$name))
subset(df, name > 3)
Usando el paquete dplyr
:
df %>%
group_by(name) %>%
filter(n() < 4)