【问题标题】:R: Extract columns of a dataframe through string matchingR:通过字符串匹配提取数据框的列
【发布时间】:2013-12-19 08:18:35
【问题描述】:

我有一个数据框,其中变量是字符串。如何仅提取至少一个值与特定字符串匹配的那些列?例如,在下面的数据框中,我想要匹配字符串“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 一起使用?你试过什么?
  • 我不知道从哪里开始。我有 389 个变量。

标签: r match subset


【解决方案1】:

首先,您可以将带有所需模式的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

【讨论】:

    【解决方案2】:

    在这一点上,我的回答并没有增加太多,但是当我发布评论时我正在手机上,所以我不愿意发布实际的答案。

    无论如何,这就是我的建议。这与@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 行 x 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 通常会稍微提高速度,但在这种情况下,似乎没有。

    【讨论】:

    • 非常令人印象深刻。很高兴知道,感谢您的详细解释。
    【解决方案3】:

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

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

    【讨论】:

    • 我不知道r 是什么,但grep 是一个unix 工具,而awk 的作用与grep 一样。
    • 好点。我删除了错误的标签。 grep 也是一个 R 函数。
    猜你喜欢
    • 2021-05-30
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多