我正在尋找一種dplyr根據字典將變數分成多列的方法:
vardic <- data.frame(varname=c('a','b','c','d'),
length=c(2,6,3,1) ) %>%
mutate(end=cumsum(length),start=end-length 1)
d <- data.frame(orig_string=c('11333333444A',
'22444444111C',
'55666666000B'))
所需的輸出是:
d2 <- data.frame(a=c(11,22,55),b=c(333333,444444,666666),c=c(444,111,000),d=c('A','C','B')
這必須僅使用 dplyr 命令來完成,因為這將通過箭頭在大于記憶體的資料集上實作(在另一個問題中提出)
更新(回復評論):dplyr只要箭頭支持,可以使用外部功能。箭頭的 R/dplyr 支持的函式串列描述了到目前為止已經實作的內容。希望這個偽代碼說明了管道:
library(tidyverse)
library(arrow)
d %>% write_dataset('myfile',format='parquet')
'myfile' %>% open_dataset %>%
sequence_of_arrowsupported_commands_to_split_columns
更新 2:添加了 cols 指示start和end位置vardic
Update3:使上面的箭頭管道更具重現性。然后測驗了@akrun 的解決方案。但separate不支持arrow
uj5u.com熱心網友回復:
基礎 R 解決方案:
# instantiate d2 with nrow(d) rows and 0 columns
d2 <- d
d2$orig_string <- NULL
for (i in seq(to = nrow(vardic))) {
d2[[vardic$varname[[i]]]] <- substr(
d$orig_string,
vardic$start[[i]],
vardic$end[[i]]
)
}
d2
a b c d
1 11 333333 444 A
2 22 444444 111 C
3 55 666666 000 B
如果您可以使用其他 tidyverse 軟體包,請使用以下解決方案purrr:pmap_dfc():
library(dplyr)
library(purrr)
library(stringr)
pmap_dfc(vardic, \(varname, start, end, ...) tibble(
!!varname := str_sub(d$orig_string, start = start, end = end)
))
# A tibble: 3 × 4
a b c d
<chr> <chr> <chr> <chr>
1 11 333333 444 A
2 22 444444 111 C
3 55 666666 000 B
uj5u.com熱心網友回復:
和其他人一樣,不確定您所說的 'only' 到底是什么意思dplyr。如果你的意思只是tidyverse, 這是一個依賴于dplyr,tidyr和的解決方案stringr:
library(dplyr)
library(stringr)
library(tidyr)
d2 <- d %>%
mutate(orig_string = str_extract_all(orig_string, "(.)\\1 (?!\\1)|[A-Z]$")) %>%
unnest_wider(orig_string)
names(d2) <- vardic$varname
# A tibble: 3 × 4
a b c d
<chr> <chr> <chr> <chr>
1 11 333333 444 A
2 22 444444 111 C
3 55 666666 000 B
uj5u.com熱心網友回復:
在這里。謝謝大家的支持。所有其他答案都面臨問題,因為回圈/映射要提取的變數所必需的動詞尚未在arrow. 然而,一種解決方案是在外部回圈并為每個變數重復箭頭命令:
例如(硬編碼序列是):
ds <- 'file' %>% open_dataset
ds <- ds %>% mutate(a=str_sub(orig_string,1,2))
ds <- ds %>% mutate(b=str_sub(orig_string,3,8))
...
ds %>% collect
現在將其重新實作為函式 回圈:
extract_var_arrow <- function(ds,var){
s <- vardic[varname==var]$start
e <- vardic[varname==var]$end
ds %>% mutate("{var}" := str_sub(orig_string,s,e)) %>% return
}
for(v in vardic$varname){
ds <- ds %>% extract_var_arrow(v)
}
請注意,在看到collect陳述句箭頭之前,它只是在編譯查詢。所以上面的回圈等價于:
# ds <- ds %>% extract_var_arrow('a')
# %>% extract_var_arrow('b')
# %>% extract_var_arrow('c')
# %>% extract_var_arrow('d')
最后我們可以收集
ds %>% select(-orig_string) %>% collect
a b c d
1 11 333333 444 A
2 22 444444 111 C
3 55 666666 000 B
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/525563.html
標籤:rdplyr阿帕奇箭头
上一篇:在R中取消列出和訪問多個串列
