R:通过字符串匹配提取数据帧的列

R:通过字符串匹配提取数据帧的列,r,match,subset,R,Match,Subset,我有一个数据帧,其中变量是字符串。如何仅提取至少有一个值与特定字符串匹配的列?例如,在下面的数据框中,我希望字符串“AB”匹配,也就是说,我希望将包含列V1、V2和V5的另一个数据框子集 V1 V2 V3 V4 V5 ABCD ABEF EFGJ AFASD JLKJLXKJ LKJAF ROGIJ GREJWI SDFS ABKLJKJX AFSD JLASDF JKLJ OIJPOI AFSD 如

我有一个数据帧,其中变量是字符串。如何仅提取至少有一个值与特定字符串匹配的列?例如,在下面的数据框中,我希望字符串“AB”匹配,也就是说,我希望将包含列V1、V2和V5的另一个数据框子集

V1      V2      V3      V4      V5
ABCD    ABEF    EFGJ    AFASD   JLKJLXKJ
LKJAF   ROGIJ   GREJWI  SDFS    ABKLJKJX
AFSD    JLASDF  JKLJ    OIJPOI  AFSD

如果列V5包含
AB

awk '$NF~"AB" {print $1,$2,$5}' OFS="\t" file
LKJAF   ROGIJ   ABKLJKJX

首先,您可以使用所需的模式对每列应用
grepl

> sapply(data, function (x) grepl('AB', x))
        V1    V2    V3    V4    V5
[1,]  TRUE  TRUE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE  TRUE
[3,] FALSE FALSE FALSE FALSE FALSE
您可以通过使用
any
包装
grepl
call来简化上述结果

> sapply(data, function (x) any(grepl('AB', x)))
   V1    V2    V3    V4    V5 
TRUE  TRUE FALSE FALSE  TRUE 
使用这样的向量,您可以轻松提取所需的列:

data[, sapply(data, function (x) any(grepl('AB', x)))]
结果是:

     V1     V2       V5
1  ABCD   ABEF JLKJLXKJ
2 LKJAF  ROGIJ ABKLJKJX
3  AFSD JLASDF     AFSD

在这一点上,我的答案并没有增加多少,但我在我的手机上发表评论,所以我觉得发布一个实际的答案并不舒服

不管怎样,下面是我的建议。它的概念与@zero323的答案几乎相同,但使用了
sapply
vapply
而不是
apply
,因为它们在
数据框的列上可能更有效:

mydf[vapply(mydf, function(x) any(grepl("AB", x)), vector(length = 1))]


为了显示速度差异,让我们在一个更大的
data.frame
上尝试一下,这个是500行乘500列

library(microbenchmark)
fun1a <- function() mydf[vapply(mydf, function(x) any(grepl("AB", x)), vector(length = 1))]
fun1b <- function() mydf[sapply(mydf, function(x) any(grepl("AB", x)))]
fun2 <- function() mydf[, apply(mydf, 2, function (x) any(grepl('AB', x)))]

set.seed(1)
nrow <- 500
ncol <- 500
x <- sample(8, nrow*ncol, replace = TRUE)
y <- lapply(x, function(z) paste(sample(LETTERS, z, replace = TRUE), collapse = ""))
mydf <- data.frame(matrix(unlist(y, use.names = FALSE), nrow = nrow))

microbenchmark(fun1a(), fun1b(), fun2(), times = 10)
# Unit: milliseconds
#     expr       min        lq    median       uq      max neval
#  fun1a()  75.46204  82.84732 101.22437 115.8292 120.5349    10
#  fun1b()  75.92004  85.82025  99.31647 108.5303 310.0216    10
#   fun2() 134.82356 168.44435 182.88842 196.4751 207.9986    10
identical(fun1a(), fun2())
# [1] TRUE
identical(fun1b(), fun2())
# [1] TRUE
库(微基准)

fun1a将grepl与sapply一起使用?你试过什么?我不知道从哪里开始。我有389个变量。我不知道
r
是什么,但是
grep
是一个unix工具,
awk
做了
grep
做的很多事情。很好。我取错标签了<代码>grep
也是一个R函数。非常令人印象深刻。很高兴知道,谢谢你的详细解释。
library(microbenchmark)
fun1a <- function() mydf[vapply(mydf, function(x) any(grepl("AB", x)), vector(length = 1))]
fun1b <- function() mydf[sapply(mydf, function(x) any(grepl("AB", x)))]
fun2 <- function() mydf[, apply(mydf, 2, function (x) any(grepl('AB', x)))]

set.seed(1)
nrow <- 500
ncol <- 500
x <- sample(8, nrow*ncol, replace = TRUE)
y <- lapply(x, function(z) paste(sample(LETTERS, z, replace = TRUE), collapse = ""))
mydf <- data.frame(matrix(unlist(y, use.names = FALSE), nrow = nrow))

microbenchmark(fun1a(), fun1b(), fun2(), times = 10)
# Unit: milliseconds
#     expr       min        lq    median       uq      max neval
#  fun1a()  75.46204  82.84732 101.22437 115.8292 120.5349    10
#  fun1b()  75.92004  85.82025  99.31647 108.5303 310.0216    10
#   fun2() 134.82356 168.44435 182.88842 196.4751 207.9986    10
identical(fun1a(), fun2())
# [1] TRUE
identical(fun1b(), fun2())
# [1] TRUE