studio inner_join cheatsheet r dplyr sqldf

inner_join - tidyverse



Resumir con condiciones en dplyr. (3)

Escribiendo el comentario de @ hadley como respuesta.

df_sqlite %>% group_by(ID) %>% mutate(Bfoo = if(A=="foo") B else 0) %>% summarize(sumB = sum(B), sumBfoo = sum(Bfoo)) %>% collect

Ilustraré mi pregunta con un ejemplo.

Data de muestra:

df <- data.frame(ID = c(1, 1, 2, 2, 3, 5), A = c("foo", "bar", "foo", "foo", "bar", "bar"), B = c(1, 5, 7, 23, 54, 202)) df ID A B 1 1 foo 1 2 1 bar 5 3 2 foo 7 4 2 foo 23 5 3 bar 54 6 5 bar 202

Lo que quiero hacer es resumir, por ID, la suma de B y la suma de B cuando A es "foo". Puedo hacer esto en un par de pasos como:

require(magrittr) require(dplyr) df1 <- df %>% group_by(ID) %>% summarize(sumB = sum(B)) df2 <- df %>% filter(A == "foo") %>% group_by(ID) %>% summarize(sumBfoo = sum(B)) left_join(df1, df2) ID sumB sumBfoo 1 1 6 1 2 2 30 30 3 3 54 NA 4 5 202 NA

Sin embargo, estoy buscando una forma más elegante / más rápida, ya que estoy tratando con 10 gb + de datos de memoria insuficiente en sqlite.

require(sqldf) my_db <- src_sqlite("my_db.sqlite3", create = T) df_sqlite <- copy_to(my_db, df)

Pensé en usar mutate para definir una nueva columna de Bfoo :

df_sqlite %>% mutate(Bfoo = ifelse(A=="foo", B, 0))

Desafortunadamente, esto no funciona en el final de la base de datos de las cosas.

Error in sqliteExecStatement(conn, statement, ...) : RS-DBI driver: (error in statement: no such function: IFELSE)


Puedes hacer ambas sumas en una sola declaración dplyr :

df1 <- df %>% group_by(ID) %>% summarize(sumB = sum(B), sumBfoo = sum(B[A=="foo"]))


Si desea hacer un recuento en lugar de resumir, entonces la respuesta es algo diferente. El cambio en el código es pequeño, especialmente en la parte de conteo condicional.

df1 <- df %>% group_by(ID) %>% summarize(countB = n(), countBfoo = sum(A=="foo")) df1 Source: local data frame [4 x 3] ID countB countBfoo 1 1 2 1 2 2 2 2 3 3 1 0 4 5 1 0