簡體   English   中英

R:通過字符串匹配提取數據幀的列

[英]R: Extract columns of a dataframe through string matching

我有一個數據框,其中變量是字符串。 如何僅提取至少一個值與特定字符串匹配的列? 例如,在下面的數據框中,我想要字符串“AB”的匹配,即我想要將包含列V1,V2和V5的另一個數據幀子集化。

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

您可以通過使用any包裝grepl調用來簡化上述結果

> 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的答案幾乎相同,但使用sapplyvapply而不是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通常會提高速度,但在這種情況下,它似乎並沒有。

如果列V5包含AB ,則使用awk打印列V1,V2和V5

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM