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