我有一个数据帧,其中变量是字符串。我怎样才能提取只有至少有一个值匹配特定字符串的列?例如,在下面的数据框中,我想要匹配字符串“AB”,即我想要将包含列V1,V2和V5的另一个数据框子集。R:通过字符串匹配提取数据帧的列
V1 V2 V3 V4 V5
ABCD ABEF EFGJ AFASD JLKJLXKJ
LKJAF ROGIJ GREJWI SDFS ABKLJKJX
AFSD JLASDF JKLJ OIJPOI AFSD
我有一个数据帧,其中变量是字符串。我怎样才能提取只有至少有一个值匹配特定字符串的列?例如,在下面的数据框中,我想要匹配字符串“AB”,即我想要将包含列V1,V2和V5的另一个数据框子集。R:通过字符串匹配提取数据帧的列
V1 V2 V3 V4 V5
ABCD ABEF EFGJ AFASD JLKJLXKJ
LKJAF ROGIJ GREJWI SDFS ABKLJKJX
AFSD JLASDF JKLJ OIJPOI AFSD
首先,您可以用所需的模式应用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
你可以通过包装grepl
简化以上结果any
> 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。 – user702432
在这一点上,我的回答不会增加太多,但我当我发布评论时,我的手机就在我的手机上,所以我不愿意发布实际的答案。
无论如何,这是我会建议的。这几乎是相同的概念@ zero323的答案,但使用sapply
或vapply
代替apply
,因为这些都可能是更有效的的data.frame
列:
mydf[vapply(mydf, function(x) any(grepl("AB", x)), vector(length = 1))]
或
mydf[sapply(mydf, function(x) any(grepl("AB", x)))]
为了显示速度差异,让我们试试更大的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
vapply
通常给出一个有点速度提升,但在这种情况下,似乎没有。
非常令人印象深刻。很高兴知道,谢谢你的详细解释。 – user702432
使用grepl和sapply?你有什么尝试? – A5C1D2H2I1M1N2O1R2T1
我不知道从哪里开始。我有389个变量。 – user702432