2011-06-28 8 views
6

definir:Crear una variable que capta la ocurrencia más frecuente por el grupo

df1 <-data.frame(
id=c(rep(1,3),rep(2,3)), 
v1=as.character(c("a","b","b",rep("c",3))) 
) 

S.T.

> df1 
    id v1 
1 1 a 
2 1 b 
3 1 b 
4 2 c 
5 2 c 
6 2 c 

Quiero crear una variable tercer freq que contiene la observación más frecuente en v1 por id S.T.

> df2 
    id v1 freq 
1 1 a b 
2 1 b b 
3 1 b b 
4 2 c c 
5 2 c c 
6 2 c c 
+1

¿cómo se supone que las ataduras se manejan dentro del grupo de identificación? – Chase

+0

@Chase En mi caso, estoy seguro de que no hay vínculos. – Fred

+0

Buena pregunta acerca de los vínculos, voy a hacer una nota sobre cómo maneja mi solución que ... – joran

Respuesta

3

Usted puede hacer esto utilizando ddply y una función personalizada para seleccionar el valor más frecuente:

myFun <- function(x){ 
    tbl <- table(x$v1) 
    x$freq <- rep(names(tbl)[which.max(tbl)],nrow(x)) 
    x 
} 

ddply(df1,.(id),.fun=myFun) 

Tenga en cuenta que which.max volverá la primera aparición del valor máximo, en el caso de los vínculos . Vea? Which.is.max en el paquete nnet para una opción que rompe lazos aleatoriamente.

+0

+1 Agradable ........ – Andrie

1
mode <- function(x) names(table(x))[ which.max(table(x)) ] 
df1$freq <- ave(df1$v1, df1$id, FUN=mode) 
> df1 
    id v1 freq 
1 1 a b 
2 1 b b 
3 1 b b 
4 2 c c 
5 2 c c 
6 2 c c 
+0

Creo que 'df2' es un error tipográfico, y cuando ejecuto esto obtengo 'NA's para' id' = 2. – joran

+0

Gracias Joran. corregido –

+0

El error se ha ido, pero todavía no creo que este código funcione. Cuando id = 2, max (tabla (x)) devuelve 3, pero la tabla (x) tiene solo 1 nombre, por lo que su modo de función devuelve NA. – joran

1

Otra forma consiste en utilizar tidyverse funciones:

  • agrupando primero, utilizando group_by(), y contando la ocurrencia de la segunda variable usando tally()
  • disponiendo por el número de ocurrencias con arrange()
  • que resume y selecciona la primera fila con summarize() y first()

Por lo tanto:

df1 %>% 
group_by(id, v1) %>% 
tally() %>% 
arrange(id, desc(n)) %>% 
summarize(freq = first(v1)) 

esto le dará sólo el mapeo (que me parece más limpio):

# A tibble: 2 x 2 
    id freq 
    <dbl> <fctr> 
1  1  b 
2  2  c 

A continuación, puede left_join su trama de datos original con esa tabla.

+0

Me gusta ese enfoque porque uno puede verificar e identificar vínculos después de 'tally()'. Eso podría ser posible con la gran función de @ joran también, pero no tan directa como aquí, al menos para mí – Tjebo

Cuestiones relacionadas