使用 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_longer
和 filter
通过从提取的第一个字符(使用 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
),使用 lapply
、replace
遍历感兴趣的列 (.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))
我有一个非常大的数据框,几乎有 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_longer
和 filter
通过从提取的第一个字符(使用 substr
)
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
来只保留在列
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
),使用 lapply
、replace
遍历感兴趣的列 (.SDcols
)不以“E”开头到 NA
,然后使用 fcoalesce
使用 do.call
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))