【问题标题】:filter variables whose column names contain pattern过滤列名包含模式的变量
【发布时间】:2018-02-12 21:55:03
【问题描述】:

我正在尝试使用dyplrfilter 函数从tbl 中过滤掉NANaNInf 值。

诀窍是我只想将过滤器应用于名称包含特定模式的列。模式为:r1、r2、r3等。

我试图结合grepfilter 来实现这一点,但无法让它发挥作用。我当前的代码如下所示:

filter_(!is.na(grep("r[1-9]", colnames(DF), value = TRUE)) 
& !is.infinite(grep("r[1-9]", colnames(DF), value = TRUE)) 
& !is.nan(grep("r[1-9]", colnames(DF), value = TRUE)))

但是,此代码返回一条警告消息:“将向量截断为长度 1。” 并且返回的数据是未经过滤的。

我怀疑是这里的is.na 函数导致了问题,因为我在网上看到了一个示例,您可以使用正常条件(即condition == value)将grep 应用于filter,而不是基于is.na的条件

【问题讨论】:

  • 你能提供一个reproducible example 你的数据集吗?
  • 我认为问题在于您正在测试colnames(DF)NANaNInf,而它应该是这些列中的值。 (与您的模式匹配的那些r[1-9]。)

标签: r regex dplyr tidyverse


【解决方案1】:

dplyr 提供了对此有用的matches()

示例 1:matches() 如何工作?

library(dplyr)

# remove columns that start with "mp"
mtcars %>% select(-matches("mp"))

# keep columns that start with "mp"
mtcars %>% select(matches("mp"))

示例 2:在请求的上下文中使用 matches(),但使用 MWE

# Create a dummy dataset
data = tibble(id = c("John","Paul","George","Ringo"),
              r1 = c(1,2,NA,NA), 
              r2 = c(1,2,NA,4),
              s1 = c(1,NA,3,4))

# Filter NAs in columns that start with r followed by a number
data %>% filter_at(vars(matches("r[0-9]")), all_vars(!is.na(.)))

【讨论】:

  • 我刚刚意识到我没有完成这个例子。现在它完成了,@anita-mcgill
【解决方案2】:

这是一种用于过滤行、比较特定列的基本 R 方法。

# sample data
set.seed(1234)
dat <- data.frame(r1=c(NA, 1,NaN, 5, Inf), r2=c(NA, 1,NaN, NA, Inf), d=rnorm(5))

这个数据集看起来像

dat
   r1  r2          d
1  NA  NA -1.2070657
2   1   1  0.2774292
3 NaN NaN  1.0844412
4   5  NA -2.3456977
5 Inf Inf  0.4291247

我们将检查前两列并忽略第三列。请注意,唯一应该保留的行是第 2 行。

dat[Reduce("&", lapply(dat[grep("^r", names(dat))], is.finite)),]
  r1 r2         d
2  1  1 0.2774292

在这里,使用grep 选择适当列(1 和2)的子集data.frame 被馈送到lapply。正则表达式“^r”表示仅包含名称以“r”开头的变量。在lapply 循环中,使用is.finite 检查每个向量。此函数为 NA、NaN 和 Inf 返回 FALSE。逻辑向量的结果列表被馈送到 Reduce` ,它返回一个逻辑向量,它是 data.frame 的行数的长度,其中一个元素为 TRUE 当且仅当一行中的每个元素都是有限的。

【讨论】:

    【解决方案3】:

    通过dplyr,您可以使用filter_at函数:

    dat %>% filter_at(vars(matches("^r[1-9]")), all_vars(is.finite(.)))
    

    使用@lmo的样本数据,结果是:

      r1 r2         d
    1  1  1 0.2774292
    

    【讨论】:

    • 您好,这行得通。但我现在发现了另一个问题,只需过滤InfNaN 值(并保留NA)即可解决。为此,我可以将第二个参数替换为 all_vars(!is.infinite(.)) &amp; all_vars(!is.nan(.))
    • @AnitaMcGill 上面我发布了一个解决方案,指向您当前的问题
    猜你喜欢
    • 2017-01-13
    • 2019-02-21
    • 2014-11-04
    • 1970-01-01
    • 2021-04-18
    • 2019-02-06
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多