我想使用自定义函数使用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
解决方案感兴趣。谢谢您的帮助。
答案 0 :(得分:2)
我们可以使用map
和lift_dl
。我们首先在每个map
上使用col.vec
(注意,由于c
展平了任何矢量元素,而list却没有,所以我使用了列表而不是向量作为输入),并应用了{{1 }}。然后,列表输出被馈送到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))
答案 1 :(得分:1)
为什么在您的by=.(..)
解决方案中使用data.table
?如果您有两行具有完全相似的值,那么这些行将合为一体。您需要修改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
等。
您的功能未完全满足您的要求。阅读上面的评论
答案 2 :(得分:0)
只需在rowwise
之前添加mutate
,以便paste
中仅使用每行的A和B值,而不是 all的向量行。
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 package(v0.2.1)于2019-02-05创建