使用 R 根据列值过滤大型数据框

Filtering a large data frame based on column values using R

我有一个非常大的数据框,几乎有 502493 行和 261 列。我想过滤它并需要具有特定代码的 ID(以 'E' 开头的代码)。这是我的数据的样子,

IDs code1 code2
1 C443 E109
2 AX31 M223
1 E341 QWE1
3 E131 M223

我需要的输出是代码仅以 'E' 开头的 ID。

IDs code
1 E109
1 E341
3 E131

我正在尝试使用 'filter' 的 dplyr 包,但没有获得所需的输出。 提前致谢

我们可以使用 pivot_longerfilter 通过从提取的第一个字符(使用 substr

创建逻辑向量来重塑为 'long' 格式
library(dplyr)
library(tidyr)
df1 %>%
   pivot_longer(cols = starts_with("code"), 
       values_to = 'code', names_to = NULL) %>%   
   filter(substr(code, 1, 1) == "E")

-输出

# A tibble: 3 × 2
    IDs code 
  <int> <chr>
1     1 E109 
2     1 E341 
3     3 E131 

如果数据真的很大,我们可以在 pivot_longer 之前做一个 filter 来只保留在列

中至少有一个 'E' 的行
df1 %>%
   filter(if_any(starts_with('code'), ~ substr(., 1, 1) == 'E')) %>% 
   pivot_longer(cols = starts_with("code"), 
       values_to = 'code', names_to = NULL) %>%   
   filter(substr(code, 1, 1) == "E")

如果是非常大的数据,另一种选择是data.table。将 data.frame 转换为 'data.table' (setDT),使用 lapplyreplace 遍历感兴趣的列 (.SDcols)不以“E”开头到 NA,然后使用 fcoalesce 使用 do.call

获取每一行的第一个非 NA 元素
library(data.table)
na.omit(setDT(df1)[, .(IDs, code = do.call(fcoalesce, 
    lapply(.SD, function(x) replace(x, substr(x, 1, 1) != "E", 
      NA)))), .SDcols = patterns("code")])

-输出

   IDs code
1:   1 E109
2:   1 E341
3:   3 E131

数据

df1 <- structure(list(IDs = c(1L, 2L, 1L, 3L), code1 = c("C443", "AX31", 
"E341", "E131"), code2 = c("E109", "M223", "QWE1", "M223")), 
class = "data.frame", row.names = c(NA, 
-4L))