我試圖避免使用 for 回圈,而是使用 tidyverse 進行迭代。具體來說,我有一個值向量,我想遍歷資料框中的單個變數以創建帶有前綴的新變數。我試過使用 dplyr::across 但是當向量長度> 1時我不成功
示例代碼:
library(tidyverse)
library(glue)
data <- data.frame(id = 1:10,
y = letters[1:10],
z = LETTERS[1:10])
letter_list <- letters[1:10]
var_naming <- function(dat, list){
dat %>%
mutate(!!glue("hx_{list}") := ifelse(y == {list}, 1, 0))
}
我試過的代碼:
**the correct dimensions of the data frame should be 13 variables and 10 observations**
# data_b outputs the correct number of observations but has 40 variables
data_b <- map(letter_list,
~var_naming(data, .x)) %>%
as.data.frame()
# data_c gives me the correct number of variables but has 100 observations
data_c <- map_df(letter_list,
~var_naming(data, .x))
# error message from data_d when using dplyr::across:
>> Error in `mutate()`:
>> ! Problem while computing `..1 =
>> across(...)`.
>> Caused by error in `across()`:
>> ! All unnamed arguments must be length 1
>> Run `rlang::last_error()` to see where the error occurred.
data_d <- data %>%
mutate(
across(
.cols = y,
.fns = ~ifelse(y == {letter_list}, 1, 0),
.names = glue("hx_{letter_list}")
))
Desired output:
id y z hx_a hx_b hx_c hx_d hx_e hx_f hx_g hx_h hx_i hx_j
1 a A 1 0 0 0 0 0 0 0 0 0
2 b B 0 1 0 0 0 0 0 0 0 0
3 c C 0 0 1 0 0 0 0 0 0 0
4 d D 0 0 0 1 0 0 0 0 0 0
5 e E 0 0 0 0 1 0 0 0 0 0
6 f F 0 0 0 0 0 1 0 0 0 0
7 g G 0 0 0 0 0 0 1 0 0 0
8 h H 0 0 0 0 0 0 0 1 0 0
9 i I 0 0 0 0 0 0 0 0 1 0
10 j J 0 0 0 0 0 0 0 0 0 1
uj5u.com熱心網友回復:
你已經接近 mutate 呼叫,但你最終想要的是一個函式串列(每個字母一個letter_list)傳遞給.fns. 由于它們是匿名函式,因此將它們命名letter_list為有助于across命名列
myFxs <- map(letter_list, ~function(y) ifelse(y == .x, 1, 0)) %>%
setNames(letter_list)
無論出于何種原因,.names膠水字符向量似乎有問題(無論如何對我來說)。由于函式是根據它們匹配的字母命名的,因此您可以使用.fn代詞 to 將模板傳遞給across
data %>%
mutate(
across(
.cols = y,
.fns = myFxs,
.names = "hx_{.fn}"
)
)
uj5u.com熱心網友回復:
代碼可以修改
- 去掉rhs 上的
{}周圍list:= - 默認情況下,最好使用
transmute而不是mutateasmutate回傳整個資料。 - 一旦我們從 中獲取列系結 (
_dfc) 資料map,將原始資料與bind_cols
library(dplyr)
library(purrr)
var_naming <- function(dat, list){
dat %>%
transmute(!!glue::glue('hx_{list}') := ifelse(y == list, 1, 0))
}
注意:list是base R構造list資料結構的函式。使用不同于保留字或已經存在的函式名稱的引數名稱創建函式可能會更好。-測驗
map_dfc(letter_list, var_naming, dat = data) %>%
bind_cols(data, .)
-輸出
id y z hx_a hx_b hx_c hx_d hx_e hx_f hx_g hx_h hx_i hx_j
1 1 a A 1 0 0 0 0 0 0 0 0 0
2 2 b B 0 1 0 0 0 0 0 0 0 0
3 3 c C 0 0 1 0 0 0 0 0 0 0
4 4 d D 0 0 0 1 0 0 0 0 0 0
5 5 e E 0 0 0 0 1 0 0 0 0 0
6 6 f F 0 0 0 0 0 1 0 0 0 0
7 7 g G 0 0 0 0 0 0 1 0 0 0
8 8 h H 0 0 0 0 0 0 0 1 0 0
9 9 i I 0 0 0 0 0 0 0 0 1 0
10 10 j J 0 0 0 0 0 0 0 0 0 1
uj5u.com熱心網友回復:
獲得相同結果的另一種方法:
data %>%
cbind(model.matrix(~y 0, .)) %>%
rename_with(~str_replace(., 'y\\B', 'hx_'))
id y z hx_a hx_b hx_c hx_d hx_e hx_f hx_g hx_h hx_i hx_j
1 1 a A 1 0 0 0 0 0 0 0 0 0
2 2 b B 0 1 0 0 0 0 0 0 0 0
3 3 c C 0 0 1 0 0 0 0 0 0 0
4 4 d D 0 0 0 1 0 0 0 0 0 0
5 5 e E 0 0 0 0 1 0 0 0 0 0
6 6 f F 0 0 0 0 0 1 0 0 0 0
7 7 g G 0 0 0 0 0 0 1 0 0 0
8 8 h H 0 0 0 0 0 0 0 1 0 0
9 9 i I 0 0 0 0 0 0 0 0 1 0
10 10 j J 0 0 0 0 0 0 0 0 0 1
如果你只考慮那些letters_list:
data %>%
mutate( y =factor(y, letter_list)) %>%
cbind(model.matrix(~y 0, .) %>%
as_tibble() %>%
select(paste0('y', letter_list)) %>%
rename_with(~str_replace(., 'y', 'hx_')))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/462257.html
上一篇:更改構面圖上的標簽
