[英]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
,我想提取mm
和yyyy
組件並使用它們將列重命名為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
兩次才能分別獲取mm
和yyyy
組件。 我也不確定如何將向量傳遞給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
(或其他函數)中提取兩個元素( yyyy
和mm
位),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.