【问题标题】:select rows that match condition in several columns在几列中选择符合条件的行
【发布时间】:2019-09-05 17:45:21
【问题描述】:

我有一个包含超过 200 万行和几列的数据集。有些列是医院代码,对应于每位患者在住院期间的所有状况。我需要为每个条件执行一些摘要,因此我正在尝试创建一个数据集,其中包含有关感兴趣的单个条件的信息。

代码有 5 位,但有时我想选择以三位开头的代码(其余两位无关紧要),例如,我希望每一行的代码在所有列中都以 401 开头包含这些代码。小例子:

id dx_1 dx_2 dx_3 dx_n
1  401  
2  2500 4011
3  18524

我想要 id 1 和 2。我尝试了一些方法,但出现错误并且速度很慢。任何指针或建议都是最受欢迎的。如果有任何不清楚的地方,我会尽力提供更多信息。

final_DB[apply(grep(paste("^", i, sep=""), final_DB[,10:29]), 1, any),]

i 对应于我想要的数字,所以在这种情况下 i <- 401 和第 10 到 29 列是此代码可能所在的所有列。

【问题讨论】:

    标签: r conditional-statements


    【解决方案1】:

    一个选项是filter_at 来选择感兴趣的列,检查任何变量是否在开头有substr, 401 以过滤行

    library(dplyr)
    df1 %>%
        filter_at(vars(starts_with("dx")), any_vars(substr(., 1, 3) == '401'))
    #    id dx_1 dx_2 dx_3 dx_n
    #1  1  401   NA   NA   NA
    #2  2 2500 4011   NA   NA
    

    或者使用base R,遍历感兴趣的列(在这种情况下,除了第一列之外的所有列),使用grepl并检查pattern“^401”是否存在 - 返回一个list 的逻辑 vectors,我们将 Reduce| 合并为单个逻辑 vector,使用它来子集数据行

    df1[Reduce(`|`, lapply(df1[-1], grepl, pattern = "^401")), ]
    

    关于 OP 帖子中的问题

    final_DB[apply(grep(paste("^", i, sep=""), final_DB[,10:29]), 1, any),]
    

    这里grep 应用于data.frame 而不是vectorgrep 应用于vector/matrices。为了更正它,我们遍历行(虽然效率很低 - 只是为了更正代码)

    i1 <- apply(final_DB[, 10:29], 1, function(x) any(grepl(paste("^", i, sep=""), x)))
    

    数据

    df1 <- structure(list(id = 1:3, dx_1 = c(401L, 2500L, 18524L), dx_2 = c(NA, 
     4011L, NA), dx_3 = c(NA, NA, NA), dx_n = c(NA, NA, NA)), 
     class = "data.frame", row.names = c(NA, -3L))
    

    【讨论】:

    • 谢谢!我特别喜欢使用filter_at,因为我开始使用tidyverse 库。
    【解决方案2】:

    我将使用mtcars 来演示一种方法(在基础 R 中)。 (顺便说一句:我不清楚你的数据是character 还是numeric,但这没关系:grep* 函数会很高兴地转换为character 来查找东西,如grepl("^123", 122:124) .. . 虽然浮点正则表达式显然应该使用grain-of-salt。)

    假设我们想要以 20 到 25 开头的每一行:

    mt <- mtcars[1:10, 1:7]
    sapply(mt, grepl, pattern = "^2[0-5]")
    #         mpg   cyl  disp    hp  drat    wt  qsec
    #  [1,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
    #  [2,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
    #  [3,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
    #  [4,]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE
    #  [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    #  [6,] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE
    #  [7,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
    #  [8,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
    #  [9,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
    # [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    

    突出显示它们是什么:

    mt
    #                    mpg   cyl    disp    hp   drat      wt    qsec
    # Mazda RX4        *21.0*    6   160.0   110   3.90   2.620   16.46
    # Mazda RX4 Wag    *21.0*    6   160.0   110   3.90   2.875   17.02
    # Datsun 710       *22.8*    4   108.0    93   3.85   2.320   18.61
    # Hornet 4 Drive   *21.4*    6  *258.0*  110   3.08   3.215   19.44
    # Hornet Sportabout 18.7     8   360.0   175   3.15   3.440   17.02
    # Valiant           18.1     6  *225.0*  105   2.76   3.460  *20.22*
    # Duster 360        14.3     8   360.0  *245*  3.21   3.570   15.84
    # Merc 240D        *24.4*    4   146.7    62   3.69   3.190  *20.00*
    # Merc 230         *22.8*    4   140.8    95   3.92   3.150  *22.90*
    # Merc 280          19.2     6   167.6   123   3.92   3.440   18.30
    

    现在使用这个:

    mt[ rowSums(sapply(mt, grepl, pattern = "^2[0-5]")) > 0, ]
    #                 mpg cyl  disp  hp drat    wt  qsec
    # Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46
    # Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02
    # Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61
    # Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44
    # Valiant        18.1   6 225.0 105 2.76 3.460 20.22
    # Duster 360     14.3   8 360.0 245 3.21 3.570 15.84
    # Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00
    # Merc 230       22.8   4 140.8  95 3.92 3.150 22.90
    

    如果您只需要检查一组特定的列,请将列选择添加到mt 中的sapply

    mt[ rowSums(sapply(mt[,c(1,4,7)], grepl, pattern = "^2[0-5]")) > 0, ]
    #                 mpg cyl  disp  hp drat    wt  qsec
    # Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46
    # Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02
    # Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61
    # Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44
    # Valiant        18.1   6 225.0 105 2.76 3.460 20.22
    # Duster 360     14.3   8 360.0 245 3.21 3.570 15.84
    # Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00
    # Merc 230       22.8   4 140.8  95 3.92 3.150 22.90
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 2013-06-02
      相关资源
      最近更新 更多