Quiero escribir un ciclo que pueda agregar el número de instancias (de ciertos valores) que se agrupan por año. Más específicamente, digamos que la variable es x1. Quiero tener dos grupos, uno es cuando x1 = 1, y el otro cuando es una combinación de algunos valores (2,3 y 5 en el siguiente ejemplo):

year    x1
2000    1
2000    1
2000    2
2000    3
2000    5

El resultado final debería verse así:

year    x2    x3
2000    2     3

Donde x2 y x3 son los recuentos cuando x1 = 1 y x1 = c (2,3,5), respectivamente. ¿Cómo se puede lograr esto?

Editar: Probablemente debería haber mencionado esto antes. Yo trabajo con dos conjuntos de datos; uno df1 es anual (que abarca aproximadamente 200 años) y el otro df2 se basa en incidentes (alrededor de 50 mil observaciones; aquí es donde se encuentra actualmente x1). Entonces, la idea del ciclo es mirar cada año [i] en df2 y agregar los recuentos agrupándolos como x2 y x3 en df1.

Edit2: Ah, resolví por qué las respuestas enviadas no funcionaban para mí. Aparentemente me encontré con el problema dplyr antes plyr discutido en este respuesta; Seguí la respuesta de ManneR y separé el pliegue. Ahora el comando group_by funciona de nuevo.

2
user6550364 25 dic. 2016 a las 23:32

3 respuestas

La mejor respuesta

No estoy seguro de lo que estaba mal con la respuesta del usuario3349904, ya que parece hacer lo que está pidiendo. No es fácil saber exactamente lo que está pidiendo sin saber cómo se ven sus datos. Si su problema con la otra solución se debe al hecho de que df1 necesita mantener los valores x2 y x3? La última parte lo resolverá.

Traté de replicar su problema desde cero, así que aquí está mi oportunidad de encontrar una solución.

library(dplyr)

#create DF1 (years)
df1 <- as.data.frame(matrix(ncol=3,nrow = 200))
df1$V1 <- c(1800:1999)
colnames(df1) <- c("year","x2","x3")

#create DF2 (transactions)
df2 <- as.data.frame(matrix(ncol=2,nrow=50000))
#add random sample data
df2$V1 <- sample(1800:1999,50000,replace = T)
df2$V2 <- sample(1:5,5000,replace = T)
colnames(df2) <- c("year","x1")

# group by year in df2 and aggregate counts based on categories
df2 %>% group_by(year) %>%
   summarise(x2 = sum(x1==1), x3 = sum(x1 %in% c(2,3,5))) -> df3

# match years in df3 and df1 and bring lookup value to df1
df1$x2 <- df3$x2[match(df1$year,df3$year)]
df1$x3 <- df3$x3[match(df1$year,df3$year)]
0
Collier 25 dic. 2016 a las 22:24

Aquí hay otra opción usando dplyr/tidyr

library(dplyr)
library(tidyr)
df1 %>%
    group_by(year, grp = paste0("x", (x1 != 1) + 2)) %>%
    summarise(x1= n()) %>% 
    spread(grp, x1)
#   year    x2    x3
#* <int> <int> <int>
#1  2000     2     3

O usando base R

xtabs(Freq~year + x1, transform(df1, x1= paste0("x", (x1!=1)+2), Freq= 1))
0
akrun 26 dic. 2016 a las 00:33

Suponiendo que está comenzando desde un marco de datos llamado df, esto contará los casos a medida que los describa por año:

library(dplyr)
df %>% group_by(year) %>% summarise(x2 = sum(x1==1), x3 = sum(x1 %in% c(2,3,5)))
-1
user3349904 25 dic. 2016 a las 21:17