`tidyr::pivot_longer` 中的 `names_sep` 参数在字符串拆分方面是否灵活?
is the `names_sep` argument in `tidyr::pivot_longer` flexible on string splitting?
我有一些从 R 模型对象中提取的随机效应系数。对于随机拦截,它们看起来像这样:
xx <- data.frame(
`Estimate.Intercept` = c(-0.1, -0.2),
`Est.Error.Intercept` = c(0.7, 0.8),
`Q5.Intercept` = c(-1.5, -1.4),
`Q95.Intercept` = c(0.7, 0.8)
)
我正在格式化 .csv
报告的数据并尝试生成 'long' 数据。frame/tibble 和 term_type
取自列的第一部分name 和 term
取自第二部分。它主要与 tidyr
包中的 pivot_longer
一起使用:
tidyr::pivot_longer(
data = xx,
cols = everything(),
names_sep = '\.',
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
结果如下所示:
# A tibble: 8 x 3
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.140
2 Est Error 0.775
3 Q5 Intercept -1.57
4 Q95 Intercept 0.773
5 Estimate Intercept -0.140
6 Est Error 0.777
7 Q5 Intercept -1.55
8 Q95 Intercept 0.792
但是它抛出这个警告:
Warning message:
Expected 2 pieces. Additional pieces discarded in 1 rows [2].
我可以使用 names_sep
项来指定我想要拆分字符串的第二个索引,但只针对第二列吗? 即 我想要 Error
而不是 Est
。我现在已经使用 ifelse
修复了它,但我想知道它是否可以在调用本身中完成。我的直觉是有一些聪明的正则表达式,或者可能是使用 stringr
的东西,但我现在很困惑...
部分列名(Est.Error.Intercept
)中有多个.
。最好使用 names_pattern
来捕获不包含任何 .
作为字符 ([^.]+
) 的组 ((...)
)。另外,用$
指定字符串的结尾
tidyr::pivot_longer(
data = xx,
cols = everything(),
names_pattern = "([^.]+)\.([^.]+)$",
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
-输出
# A tibble: 8 × 3
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.1
2 Error Intercept 0.7
3 Q5 Intercept -1.5
4 Q95 Intercept 0.7
5 Estimate Intercept -0.2
6 Error Intercept 0.8
7 Q5 Intercept -1.4
8 Q95 Intercept 0.8
"([^.]+)\.([^.]+)$"
- 捕获为两组 1) ([^.]+)
- 一个或多个不是 .
的字符,后跟 .
(\.
) 和 2) 第二组字符不是 .
直到字符串的末尾 ($
)。
您可以先使用 rename_with
保留 names_sep
:
library(dplyr)
library(stringr)
xx %>%
rename_with(~str_replace(., '.Intercept', '_Intercept')) %>%
tidyr::pivot_longer(
cols = everything(),
names_sep = '\_',
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.1
2 Est.Error Intercept 0.7
3 Q5 Intercept -1.5
4 Q95 Intercept 0.7
5 Estimate Intercept -0.2
6 Est.Error Intercept 0.8
7 Q5 Intercept -1.4
8 Q95 Intercept 0.8
我有一些从 R 模型对象中提取的随机效应系数。对于随机拦截,它们看起来像这样:
xx <- data.frame(
`Estimate.Intercept` = c(-0.1, -0.2),
`Est.Error.Intercept` = c(0.7, 0.8),
`Q5.Intercept` = c(-1.5, -1.4),
`Q95.Intercept` = c(0.7, 0.8)
)
我正在格式化 .csv
报告的数据并尝试生成 'long' 数据。frame/tibble 和 term_type
取自列的第一部分name 和 term
取自第二部分。它主要与 tidyr
包中的 pivot_longer
一起使用:
tidyr::pivot_longer(
data = xx,
cols = everything(),
names_sep = '\.',
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
结果如下所示:
# A tibble: 8 x 3
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.140
2 Est Error 0.775
3 Q5 Intercept -1.57
4 Q95 Intercept 0.773
5 Estimate Intercept -0.140
6 Est Error 0.777
7 Q5 Intercept -1.55
8 Q95 Intercept 0.792
但是它抛出这个警告:
Warning message:
Expected 2 pieces. Additional pieces discarded in 1 rows [2].
我可以使用 names_sep
项来指定我想要拆分字符串的第二个索引,但只针对第二列吗? 即 我想要 Error
而不是 Est
。我现在已经使用 ifelse
修复了它,但我想知道它是否可以在调用本身中完成。我的直觉是有一些聪明的正则表达式,或者可能是使用 stringr
的东西,但我现在很困惑...
部分列名(Est.Error.Intercept
)中有多个.
。最好使用 names_pattern
来捕获不包含任何 .
作为字符 ([^.]+
) 的组 ((...)
)。另外,用$
tidyr::pivot_longer(
data = xx,
cols = everything(),
names_pattern = "([^.]+)\.([^.]+)$",
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
-输出
# A tibble: 8 × 3
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.1
2 Error Intercept 0.7
3 Q5 Intercept -1.5
4 Q95 Intercept 0.7
5 Estimate Intercept -0.2
6 Error Intercept 0.8
7 Q5 Intercept -1.4
8 Q95 Intercept 0.8
"([^.]+)\.([^.]+)$"
- 捕获为两组 1) ([^.]+)
- 一个或多个不是 .
的字符,后跟 .
(\.
) 和 2) 第二组字符不是 .
直到字符串的末尾 ($
)。
您可以先使用 rename_with
保留 names_sep
:
library(dplyr)
library(stringr)
xx %>%
rename_with(~str_replace(., '.Intercept', '_Intercept')) %>%
tidyr::pivot_longer(
cols = everything(),
names_sep = '\_',
names_to = c('term_type', 'term'),
values_to = 'term_val'
)
term_type term term_val
<chr> <chr> <dbl>
1 Estimate Intercept -0.1
2 Est.Error Intercept 0.7
3 Q5 Intercept -1.5
4 Q95 Intercept 0.7
5 Estimate Intercept -0.2
6 Est.Error Intercept 0.8
7 Q5 Intercept -1.4
8 Q95 Intercept 0.8