我想基于谓词函数(例如is.character
,和“选择帮助器”(例如starts_with("Z")
)以编程方式选择要突变的列同时。
library(dplyr)
df <- tibble(V1 = "a", V2 = 1, Z1 = "a", Z2 = 1)
所需的输出(mutate_at(df, "Z1", paste, "b")
,但未明确选择Z1
):
structure(list(V1 = "a", V2 = 1, Z1 = "a b", Z2 = 1), class = c(
"tbl_df", "tbl", "data.frame"
), row.names = c(NA, -1L))
换句话说,如何在单个突变中“组合” mutate_at(df, vars(starts_with("Z")), paste, "b")
和mutate_if(df, is.character, paste, "b")
?
答案 0 :(得分:5)
为什么不使用两个步骤?
df %>%
select_if(is.character) %>%
select(starts_with("Z"))
编辑:
select_if(df, is.character) %>%
select(starts_with("Z")) %>%
names() %>%
mutate_at(df, ., paste, "b")
答案 1 :(得分:3)
我们可以使用基本功能为.predicate
生成mutate_if
:
df %>% mutate_if(sapply(., is.character) & startsWith(names(.), 'Z'), ~ paste(., 'b'))
# # A tibble: 1 x 4
# V1 V2 Z1 Z2
# <chr> <dbl> <chr> <dbl>
# 1 a 1 a b 1
答案 2 :(得分:2)
那为什么不走三步;)?
df2 <- df %>%
select_if(is.character) %>%
select(starts_with("Z")) %>%
mutate_all(funs(paste(., "b")))
for (i in names(df2)) {
df[[i]] <- df2[[i]]
}
答案 3 :(得分:1)
在较新版本的tidyselect和dplyr中,我们可以使用where
将谓词功能转换为选择助手。
df %>%
mutate(across(where(is.character) & starts_with("Z"), paste, "b"))
#> # A tibble: 1 x 4
#> V1 V2 Z1 Z2
#> <chr> <dbl> <chr> <dbl>
#> 1 a 1 a b 1
我们还必须使用更新的across
接口,因为mutate_at
与where
不兼容。