Utilizo purrr ::: iwalk de esta manera, pero no hace lo que quiero:

purrr:::iwalk(DGE_tables, ~ .x[-which(.x$column1 %in% VectorOfSpecificValues),])

DGE_tables es una lista de marcos de datos. En esto, todos los marcos de datos quiero eliminar filas que tienen valores específicos en la columna1. Los marcos de datos tienen la misma estructura.

¿Es posible hacer eso con purrr ::: iwalk ? ¿O hay una mejor manera de hacerlo?

EDITAR : un ejemplo:

La lista de trama de datos:

DGE_tables
# Display
$dataframe1
    column1   column2
1   to_delete    56
2   to_keep      45

$dataframe2
    column1   column2
1   to_delete    78
2   to_keep      27

...

Así que quiero eliminar filas que tienen $ column1 = "to_delete". Me gusta esto:

# wanted result
$dataframe1
    column1   column2
1   to_keep      45

$dataframe2
    column1   column2
1   to_keep      27

...
1
Adam Bellaïche 10 may. 2019 a las 16:57

3 respuestas

La mejor respuesta

Una opción sería filter

library(tidyverse)
map(DGE_tables, ~ .x %>% 
                  filter(column1 != "to_delete"))
#[[1]]
#  column1 column2
#1 to_keep      45

#[[2]]
#  column1 column2
#1 to_keep      27

O con slice

map(DGE_tables, ~ .x %>% 
                  slice(which(column1 != "to_delete")))

O también se puede hacer con base R

lapply(DGE_tables, subset, subset = column1 != "to_delete")

NOTA: El conjunto de datos del OP es un list de data.frame y necesita una salida de retorno a list de data.frame s con un subconjunto de filas

Y no funcionaría con keep o discard

purrr::keep(DGE_tables, ~ .x[['column1']] == 'to keep')

Error: las funciones de predicado deben devolver un solo TRUE o FALSE, no un vector lógico de longitud 2

Datos

DGE_tables <- list(structure(list(column1 = c("to_delete", "to_keep"), 
   column2 = c(56L, 
45L)), class = "data.frame", row.names = c("1", "2")), structure(list(
    column1 = c("to_delete", "to_keep"), column2 = c(78L, 27L
    )), class = "data.frame", row.names = c("1", "2")))
1
akrun 10 may. 2019 a las 14:28

purrr tiene keep() y discard() solo para este tipo de cosas:

library(purrr)

l <- list(
    list(col1 = 'to keep', col2 = 1),
    list(col1 = 'to discard', col2 = 2)
)

purrr::keep(l, ~ .x[['col1']] == 'to keep')
#> [[1]]
#> [[1]]$col1
#> [1] "to keep"
#> 
#> [[1]]$col2
#> [1] 1
purrr::discard(l, ~ .x[['col1']] == 'to discard')
#> [[1]]
#> [[1]]$col1
#> [1] "to keep"
#> 
#> [[1]]$col2
#> [1] 1
3
npjc 10 may. 2019 a las 14:13

Hay algunas cosas en el trabajo aquí. Como no tengo tus datos (¿todavía?), Haré los míos, de manera bastante cruda:

dge <- list(mtcars[1:5,], mtcars[1:5,])

Algunos problemas:

  1. Por definición, purrr::walk y purrr::iwalk devuelven el marco original .x, independientemente de lo que haga en el bloque de funciones . Como ejemplo, mira esto:

    (purrr::iwalk(dge, ~ return(NULL)))
    # [[1]]
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    # [[2]]
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    

    (Si solo hace purrr::iwalk(dge, ...) sin los parens circundantes, no verá nada porque el valor predeterminado es devolver el valor de retorno invisiblemente . Los parens obligan a que sea visible).

    Entonces, el punto difícil aquí es que su ejemplo de simplemente filtrar dentro de iwalk no funcionará. Para eso, probablemente quieras purrr::imap. (Si está haciendo más y el pequeño ejemplo en su pregunta era un fragmento más corto de más código, entonces probablemente todavía sea bueno con iwalk).

  2. Tiendo a preferir no usar which en bloques como ese, ya que la ausencia de negación de which puede ser problemática (el vector vacío negativo no hace "nada") . En cambio, sugiero usar vectores lógicos y no vectores enteros.

    Ejemplos: probaré un estúpido condicional de 1 %in% 2, que obviamente no debería encontrar nada (y con su negación, devolver todas las filas):

    dge[[1]][ -which(1 %in% 2), ]
    #  [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
    # <0 rows> (or 0-length row.names)
    

    El uso de un vector lógico en su lugar (y ! en lugar de -) devuelve lo que esperamos (es decir, todas las filas):

    dge[[1]][ !(1 %in% 2), ]
    #                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
    # Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    # Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    # Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    # Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    # Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    
2
r2evans 10 may. 2019 a las 14:15