R:在正则表达式中使用 Summarize() across() 和 where()
R: Using Summarize() accross() and where() with regular expressions
我有以下数据集:
Lines <- "id time sex Age Obs_A Obs_B Obs_C
1 1 male 90 0 0 0
1 2 male 91 0 0 0
1 3 male 92 1 1 0
2 1 female 87 0 1 1
2 2 female 88 0 1 0
2 3 female 89 0 0 1
3 1 male 50 0 1 0
3 2 male 51 1 0 0
3 3 male 52 0 0 0
4 1 female 54 0 1 0
4 2 female 55 0 1 0
4 3 female 56 0 1 0"
我想将 summarize
与正则表达式 (grepl
) 结合使用,以便重新格式化以 Obs
开头的变量(例如取中位数),同时对其他操作进行其他操作变量。例如这样的事情:
TTE <- TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(id = first(id), sex = first(sex),
Age = mean(Age), across(where(grepl("Obs")), mean), across(where(is.numeric), max)) %>%
ungroup
尽管如此,我收到以下错误:
x argument "x" is missing, with no default
关于如何以一致的方式使用 summarize()
、across()
、where()
和 grepl()
有什么想法吗?
对于 dplyr
,您可以使用 tidyselect 函数来 across
中的 select 列。
library(dplyr)
TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(Age = mean(Age),
across(starts_with('Obs'), mean),
across(where(is.numeric), max)) %>%
ungroup
# id sex Age Obs_A Obs_B Obs_C time
# <int> <chr> <dbl> <dbl> <dbl> <dbl> <int>
#1 1 male 91 0.333 0.333 0 3
#2 2 female 88 0 0.667 0.667 3
#3 3 male 51 0.333 0.333 0 3
#4 4 female 55 0 1 0 3
由于您是按所有字符列分组的,因此不需要将它们包含在 across
中。
正如 OP 提到的关于使用 regex
,一个选项是 matches
,与 starts_with
或 end_with
或 contains
相比,它可以采用正则表达式。此外,我们不需要使用 ungroup
,因为 summarise
中有一个选项可以指定 .groups
,即即使我们在 summarise
之后使用 ungroup
,如果我们指定 .groups
,将会出现一条警告消息,可以避免该消息
library(dplyr)
TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(Age = mean(Age),
across(matches('^[Oo]bs'), mean),
across(where(is.numeric), max), .groups = 'drop')
-输出
# A tibble: 4 x 7
id sex Age Obs_A Obs_B Obs_C time
<int> <chr> <dbl> <dbl> <dbl> <dbl> <int>
1 1 male 91 0.333 0.333 0 3
2 2 female 88 0 0.667 0.667 3
3 3 male 51 0.333 0.333 0 3
4 4 female 55 0 1 0 3
请注意,where
主要用于检查列的值,而不是列名。为此,我们需要使用 select-helpers
我有以下数据集:
Lines <- "id time sex Age Obs_A Obs_B Obs_C
1 1 male 90 0 0 0
1 2 male 91 0 0 0
1 3 male 92 1 1 0
2 1 female 87 0 1 1
2 2 female 88 0 1 0
2 3 female 89 0 0 1
3 1 male 50 0 1 0
3 2 male 51 1 0 0
3 3 male 52 0 0 0
4 1 female 54 0 1 0
4 2 female 55 0 1 0
4 3 female 56 0 1 0"
我想将 summarize
与正则表达式 (grepl
) 结合使用,以便重新格式化以 Obs
开头的变量(例如取中位数),同时对其他操作进行其他操作变量。例如这样的事情:
TTE <- TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(id = first(id), sex = first(sex),
Age = mean(Age), across(where(grepl("Obs")), mean), across(where(is.numeric), max)) %>%
ungroup
尽管如此,我收到以下错误:
x argument "x" is missing, with no default
关于如何以一致的方式使用 summarize()
、across()
、where()
和 grepl()
有什么想法吗?
对于 dplyr
,您可以使用 tidyselect 函数来 across
中的 select 列。
library(dplyr)
TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(Age = mean(Age),
across(starts_with('Obs'), mean),
across(where(is.numeric), max)) %>%
ungroup
# id sex Age Obs_A Obs_B Obs_C time
# <int> <chr> <dbl> <dbl> <dbl> <dbl> <int>
#1 1 male 91 0.333 0.333 0 3
#2 2 female 88 0 0.667 0.667 3
#3 3 male 51 0.333 0.333 0 3
#4 4 female 55 0 1 0 3
由于您是按所有字符列分组的,因此不需要将它们包含在 across
中。
正如 OP 提到的关于使用 regex
,一个选项是 matches
,与 starts_with
或 end_with
或 contains
相比,它可以采用正则表达式。此外,我们不需要使用 ungroup
,因为 summarise
中有一个选项可以指定 .groups
,即即使我们在 summarise
之后使用 ungroup
,如果我们指定 .groups
library(dplyr)
TTE %>%
group_by(id, across(where(is.character))) %>%
summarise(Age = mean(Age),
across(matches('^[Oo]bs'), mean),
across(where(is.numeric), max), .groups = 'drop')
-输出
# A tibble: 4 x 7
id sex Age Obs_A Obs_B Obs_C time
<int> <chr> <dbl> <dbl> <dbl> <dbl> <int>
1 1 male 91 0.333 0.333 0 3
2 2 female 88 0 0.667 0.667 3
3 3 male 51 0.333 0.333 0 3
4 4 female 55 0 1 0 3
请注意,where
主要用于检查列的值,而不是列名。为此,我们需要使用 select-helpers