是否可以删除purrr ::: iwalk .x中的某些行?

时间:2019-05-10 13:57:04

标签: r list dataframe purrr

我这样使用 purrr ::: iwalk ,但它不能满足我的要求:

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

DGE_tables是数据帧列表。在所有这些数据框中,我要删除column1中具有特定值的行。数据帧具有相同的结构。

是否可以使用 purrr ::: iwalk 来做到这一点?还是有更好的方法呢?

编辑:示例:

数据框列表:

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

...

所以我想删除具有$ column1 =“ to_delete”的行。像这样:

# wanted result
$dataframe1
    column1   column2
1   to_keep      45

$dataframe2
    column1   column2
1   to_keep      27

...

3 个答案:

答案 0 :(得分:3)

purrr具有keep()discard()就是为了这种事情:

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

答案 1 :(得分:2)

这里有一些事情在起作用。由于我还没有您的数据(还好吗?),所以我会做我自己的,很粗略的:

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

一些问题:

  1. 根据定义,purrr::walkpurrr::iwalk返回原始帧.x无论您在功能块中做什么。作为示例,请参见:

    (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
    

    (如果您只是purrr::iwalk(dge, ...)而没有周围的括号,那么您将看不到任何东西,因为默认值是返回返回值 invisible(无形)。括号会强制其可见。 )

    因此,这里的难点在于,仅在iwalk内进行过滤的示例将不起作用。为此,您可能需要purrr::imap。 (如果您做得更多,而问题中的一个小例子是更多代码的较短片段,那么您可能对iwalk仍然满意。)

  2. 我倾向于在这样的块中使用which,因为缺少which的取反会带来问题(负空向量确实会不做任何事)。相反,我建议使用逻辑向量,而不是整数向量。

    示例:我将尝试一个愚蠢的条件1 %in% 2,该条件显然应该什么也找不到(并且通过您的否定,返回所有行):

    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)
    

    使用逻辑矢量(和!代替-)返回我们期望的值(即所有行):

    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 :(得分:1)

一个选项是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

或与slice

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

或者也可以用base R完成

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

注意:OP的数据集是list的{​​{1}},并且需要返回data.frame的{​​{1}}和行的子集

,它不适用于listdata.frame

keep
  

错误:谓词函数必须返回单个discardpurrr::keep(DGE_tables, ~ .x[['column1']] == 'to keep') ,而不能返回   长度为2的逻辑向量

数据

TRUE