我正在尝试使用dyplr的filter函数从tbl中过滤出NA、NaN和Inf值。
诀窍是,我只想将过滤器应用于名称包含特定模式的列。模式是: r1、r2、r3等。
我曾尝试将grep和filter结合起来来实现这一点,但无法使其正常工作。我当前的代码如下所示:
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)))但是,此代码将返回一条警告消息:"Truncating vector to length 1“。并且返回的数据未经过过滤。
我怀疑是这里的is.na函数导致了这个问题,因为我在网上看到过一个示例,其中您可以使用普通条件(即condition == value)而不是基于is.na的条件将grep应用于filter
发布于 2017-09-05 00:46:02
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(.)))发布于 2017-09-05 00:17:48
下面是一个基数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`,Reduce`返回一个逻辑向量,即当且仅当一行中的每个元素都是有限的时,元素为真的data.frame的行数的长度。
发布于 2017-09-05 00:53:00
对于dplyr,您可以使用filter_at函数:
dat %>% filter_at(vars(matches("^r[1-9]")), all_vars(is.finite(.)))使用@lmo的样本数据,结果是:
r1 r2 d 1 1 1 0.2774292
https://stackoverflow.com/questions/46040803
复制相似问题