我正在尝试在谓词函数中使用带有列名的动词mutate_if
或select_if
等。
请参阅以下示例:
> btest <- data.frame(
+ sjr_first = c('1','2','3',NA, NA, '6'),
+ jcr_first = c('1','2','3',NA, NA, '6'),
+ sjr_second = LETTERS[1:6],
+ jcr_second = LETTERS[1:6],
+ sjr_third = as.character(seq(6)),
+ jcr_fourth = seq(6) + 5,
+ stringsAsFactors = FALSE)
>
> btest %>% select_if(.predicate = ~ str_match(names(.), 'jcr'))
Error in selected[[i]] <- eval_tidy(.p(column, ...)) :
replacement has length zero
我知道我可以使用btest %>% select_at(vars(dplyr::matches('jcr')))
但我的目标实际上是将列名条件与另一个条件相结合(例如is.numeric
( 使用mutate_if()
对我的列的子集进行操作。但是我不确定如何让具有名称匹配的第一部分工作......
你可以做:
btest %>%
select_if(str_detect(names(.), "jcr") & sapply(., is.numeric))
jcr_fourth
1 6
2 7
3 8
4 9
5 10
6 11
Tidyverse 解决方案:
require(dplyr)
# Return (get):
btest %>%
select_if(grepl("jcr", names(.)) & sapply(., is.numeric))
# Mutate (set):
btest %>%
mutate_if(grepl("jcr", names(.)) & sapply(., is.numeric), funs(paste0("whatever", .)))
基本 R 解决方案:
# Return (get):
btest[,grepl("jcr", names(btest)) & sapply(btest, is.numeric), drop = FALSE]
# Mutate (set):
btest[,grepl("jcr", names(btest)) & sapply(btest, is.numeric)] <- paste0("whatever", unlist(btest[,grepl("jcr", names(btest)) & sapply(btest, is.numeric)]))
您可以将两个select_if
调用分开
library(dplyr)
library(stringr)
btest %>% select_if(str_detect(names(.), 'jcr')) %>% select_if(is.numeric)
# jcr_fourth
#1 6
#2 7
#3 8
#4 9
#5 10
#6 11
我们不能合并这两个调用,因为第一个调用一起对整个数据帧进行操作,而第二个调用按列操作。