结合选择助手和谓词功能以在dplyr中进行突变

时间:2018-08-23 09:20:46

标签: r dplyr

我想基于谓词函数(例如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")

4 个答案:

答案 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_atwhere不兼容。