![](/img/trans.png)
[英]Create multiple columns with mutate (dplyr) in R using rollapplyr function
[英]R dplyr mutate multiple columns using custom function to create new column
我想使用自定義函數使用dplyr::mutate
在data.frame中創建新列,該參數是data.frame的列名的向量,但我得到以下輸出:
customFun <- function(col.vec) {
paste0(gsub("\\s", "_", col.vec), collapse = "-")
}
df <- data.frame(A = c("x 1", "x", "x w"), B = c("E", "D", "2 w"), stringsAsFactors = FALSE)
df %>%
mutate(C = customFun(c(A, B)))
A B C
1 x 1 E x_1-x-x_w-E-D-2_w
2 x D x_1-x-x_w-E-D-2_w
3 x w 2 w x_1-x-x_w-E-D-2_w
代替:
data.table::data.table(df)[, C := customFun(c(A, B)), by = .(A, B)]
A B C
1: x 1 E x_1-E
2: x D x-D
3: x w 2 w x_w-2_w
它可以通過多種方式實現,但我只對dplyr
解決方案感興趣。 謝謝您的幫助。
我們可以使用map
和lift_dl
。 我們首先map
每個col.vec
(注意我使用了列表而不是向量作為輸入,因為c
平任何向量元素,而列表沒有)並應用gsub
。 然后將列表輸出送入paste
。 由於paste
需要...
,我們可以使用purrr::lift_dl
將其輸入域從...
提升到list
類型:
library(dplyr)
library(purrr)
customFun <- function(col.vec) {
map(col.vec, ~gsub("\\s", "_", .x)) %>%
lift_dl(paste, sep = "-")()
}
df %>%
mutate(C = customFun(list(A, B)))
或者...
作為輸入:
customFun <- function(...) {
col.vec <- list(...)
map(col.vec, ~gsub("\\s", "_", .x)) %>%
lift_dl(paste, sep = "-")()
}
df %>%
mutate(C = customFun(A, B))
輸出:
A B C
1 x 1 E x_1-E
2 x D x-D
3 x w 2 w x_w-2_w
為什么在data.table
解決方案中使用by=.(..)
? 如果你有兩行具有完全相似的值,那么這些行將折疊成一行。 您需要修改customFun
。 它的方式不正確:
library(tidyverse)
customFun = function(data) invoke(paste, data.frame(gsub('\\s+', '_', as.matrix(data))), sep='-')
df %>%
mutate(c = customFun(.))
A B C
1 x 1 E x_1-E
2 x D x-D
3 x w 2 w x_w-2_w
你可以用do.call
替換調用甚至lift
等。
你的功能並沒有完全符合你的要求。 閱讀上面的評論
只需添加rowwise
您之前mutate
所以只有每行的A和B值中使用paste
,而不是所有行的載體。
library(dplyr)
df %>%
rowwise() %>%
mutate(C = customFun(c(A, B)))
#> Source: local data frame [3 x 3]
#> Groups: <by row>
#>
#> # A tibble: 3 x 3
#> A B C
#> <chr> <chr> <chr>
#> 1 x 1 E x_1-E
#> 2 x D x-D
#> 3 x w 2 w x_w-2_w
由reprex包創建於2019-02-05(v0.2.1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.