我从 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
报告格式化数据并尝试生成一个“长”data.frame/tibble,其中 term_type
取自列名的第一部分,term
取自第二部分。它主要适用于 pivot_longer
包中的 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
修复了它,但我想知道它是否可以在调用本身中完成。我的直觉是有一些聪明的 regex,或者可能是使用 stringr
的东西,但我现在很难过......
回答1
某些列名 (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) 第二组不是 .
的字符w109> 直到字符串的结尾 ($
)。
回答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