r - `tidyr::pivot_longer` 中的 `names_sep` 参数对字符串拆分是否灵活?

我从 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

相似文章

r - R pivot_longer() 在输出中有 NA

我无法旋转我的数据。我可以使用一种解决方法来产生我想要的输出(如下所示),但我怀疑它可能在单个pivot_longer()调用中,我只是无法弄清楚该命令。任何建议/帮助将不胜感激。library(dp...

r - 具有多个新列的 Pivot_longer()

我有一个关于tidyr::pivot_longer()的问题。假设我从一个虚构的数据框开始。想象一下人们被问到两个关于两个流派的问题。SQ1_2将是关于第一种类型的第二个问题。set.seed(123...