簡體   English   中英

提取部分列名進行重命名

[英]Extract parts of column names for renaming

我有一個 dataframe 其中一些列被命名為日期。 例如,像這樣:

df_1 <- data_frame("id" = c('a','b','c','d'),
                 "gender" = c('m','f','f','m'),
                 "05/16/2017" = c(1,2,3,4),
                 "11/08/2016" = c(1,2,3,4),
                 "08/15/2016" = c(1,2,3,4))

df_1
# A tibble: 4 x 5
  id    gender `05/16/2017` `11/08/2016` `08/15/2016`
  <chr> <chr>         <dbl>        <dbl>        <dbl>
1 a     m                 1            1            1
2 b     f                 2            2            2
3 c     f                 3            3            3
4 d     m                 4            4            4

對於當前日期的列,格式mm/dd/yyyy ,我想提取mmyyyy組件並使用它們將列重命名為election_yyyy_mm 即我最終會得到如下所示的 df:

df_2 <- data_frame("id" = c('a','b','c','d'),
                 "gender" = c('m','f','f','m'),
                 "election_2017_05" = c(1,2,3,4),
                 "election_2016_11" = c(1,2,3,4),
                 "election_2016_08" = c(1,2,3,4))

df_2
# A tibble: 4 x 5
  id    gender election_2017_05 election_2016_11 election_2016_08
  <chr> <chr>             <dbl>            <dbl>            <dbl>
1 a     m                     1                1                1
2 b     f                     2                2                2
3 c     f                     3                3                3
4 d     m                     4                4                4

我想我有一個涉及stringr的部分解決方案,但目前我必須運行str_extract兩次才能分別獲取mmyyyy組件。 我也不確定如何將向量傳遞給rename()

這是我到目前為止的兩個片段:

stringr::str_extract(c("05/16/2017", "11/08/2016", "08/15/2016"), "^[^/]+")
[1] "05" "11" "08"

stringr::str_extract(c("05/16/2017", "11/08/2016", "08/15/2016"), "[0-9]{4}")
[1] "2017" "2016" "2016"

誰能幫我a)在一次調用str_extract (或其他函數)中提取兩個元素( yyyymm位),b)將結果向量傳遞給rename

使用 tidyverse(dplyr 和 stringr),我們可以像這樣重命名列:

library(dplyr)

df_1 %>% 
  rename_with(
    .cols = contains("/"), # selects only the date columns
    ~ paste0(
      "election_",  
      stringr::str_sub(.x, -4, -1), # last 4 digits/letters
      "_",
      stringr::str_sub(.x, 1, 2) # first 2 digits/letters
    )
  )

結果:

# A tibble: 4 x 5
  id    gender election_2017_05 election_2016_11 election_2016_08
  <chr> <chr>             <dbl>            <dbl>            <dbl>
1 a     m                     1                1                1
2 b     f                     2                2                2
3 c     f                     3                3                3
4 d     m                     4                4                4

我們可以使用rename_with來重命名 function。 在重命名 function 中,我們可以先用mdy()將字符解析為日期,然后提取month()year() 最后, glue()將元素重新組合在一起。

library(dplyr)
library(glue)
library(lubridate)

df_1 %>% rename_with( ~glue('election_{year(mdy(.x))}_{month(mdy(.x))}'),
                      matches("\\d{2}/\\d{2}/\\d{4}"))

output

# A tibble: 4 × 5
  id    gender election_2017_5 election_2016_11 election_2016_8
  <chr> <chr>            <dbl>            <dbl>           <dbl>
1 a     m                    1                1               1
2 b     f                    2                2               2
3 c     f                    3                3               3
4 d     m                    4                4               4

我們還可以使用stringr::string_extract_all來處理向量而不是單個字符元素。 使用來自 OP 嘗試的修改后的正則表達式,我們可以在一次調用中提取月份和年份。 只需從字符串的開頭 ( ^ ) 或結尾 ( $ ) 提取 ( | ) 數字 ( \\d+ ): "^\\d+|\\d+$"

答案是這樣的:

df_1 %>% rename_with( ~stringr::str_extract_all(.x, "^\\d+|\\d+$") %>%
                              map_chr(~glue('election_{.x[2]}_{.x[1]}')),
                      matches("\\d{2}/\\d{2}/\\d{4}"))

另一種使用dplyr但沒有stringr的方法。

這里使用rename_with到 select 出列/ ,在/上拆分字符串並使用 sapply 將拆分的結果連接在一起作為可用於重命名的向量。


df_1 %>%
    rename_with(.cols = contains('/'),
    ~ strsplit(.x, '/') %>% 
    sapply(
      function(x) paste0('election_',as.character(x[3]),'_',as.character(x[2])),
      simplify=TRUE)
    )

這是使用正則表達式的單行代碼:

names(df_1) <- sub("(\\d+).*?(\\d+)$", "election_\\2_\\1", names(df_1))

這是如何工作的:首先,您將列名分為兩個捕獲組:

  • (\\d+) : 第一個捕獲組,捕獲前兩位數
  • .*? 之后的任何事情直到...
  • (\\d+)$ : ... 第二個捕獲組,捕獲最后一個數字。

然后,使用sub的替換參數,將字符串election_添加到匹配的名稱中,並使用反向引用\\1\\2以相反的順序引用兩個捕獲組。

使用stringr

library(stringr)
names(df_1) <- str_replace(names(df_1), "(\\d+).*?(\\d+)$", "election_\\2_\\1")

結果:

df_1 
# A tibble: 4 × 5
  id    gender election_2017_05 election_2016_11 election_2016_08
  <chr> <chr>             <dbl>            <dbl>            <dbl>
1 a     m                     1                1                1
2 b     f                     2                2                2
3 c     f                     3                3                3
4 d     m                     4                4                4

這是另一種方法:

library(dplyr)
library(stringr)
df_1 %>% 
  rename_with(~str_c('election',str_sub(.x, -4,-1),str_sub(.x,-10,-9), sep = "_"), where(is.numeric))
  id    gender election_2017_05 election_2016_11 election_2016_08
  <chr> <chr>             <dbl>            <dbl>            <dbl>
1 a     m                     1                1                1
2 b     f                     2                2                2
3 c     f                     3                3                3
4 d     m                     4                4                4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM