我经常需要在dataframes中使用mutate()
或select()
,条件应用于变量的子集,但我不能始终如一地这样做。
玩具示例数据框:
data<-data.frame(id=c("John", "Jane", "Louis", "Mirian"),
a=c(FALSE, FALSE, TRUE, TRUE),
b=c(FALSE, NA, TRUE, NA),
c=c(TRUE, FALSE, TRUE, TRUE),
num=1:4)
操作1:mutate(),对逻辑变量执行行操作:-我想创建一个新列"abc_any",当a:c中的任何一个值为真时,该列的值为真:
我通常使用:
data%>%mutate(abc_any=a|b|c)
id a b c num abc_any
1 John FALSE FALSE TRUE 1 TRUE
2 Jane FALSE NA FALSE 2 NA
3 Louis TRUE TRUE TRUE 3 TRUE
4 Mirian TRUE NA TRUE 4 TRUE
但我不能在链式“|”比较中不指定所有变量a:c。
我尝试了以下方法,结果不一致。不知道为什么:
data%>%mutate(abc_any=Reduce("|", a:c))
id a b c num abc_any
1 John FALSE FALSE TRUE 1 TRUE
2 Jane FALSE NA FALSE 2 TRUE
3 Louis TRUE TRUE TRUE 3 TRUE
4 Mirian TRUE NA TRUE 4 TRUE
这是可行的,但令人惊讶的是abc_any强制为数字:
data%>%rowwise()%>%mutate(abc_any=Reduce("|", a:c))
# A tibble: 4 x 6
# Rowwise:
id a b c num abc_any
<fct> <lgl> <lgl> <lgl> <int> <int>
1 John FALSE FALSE TRUE 1 1
2 Jane FALSE NA FALSE 2 0
3 Louis TRUE TRUE TRUE 3 1
4 Mirian TRUE NA TRUE 4 1
这不起作用,并抛出几个错误消息:
data%>%rowwise()%>%mutate(abc_any=apply(a:c, 1, any))
操作#2:filter()-我有时想用类似的条件进行筛选,但不能:
data%>%filter(a|b|c)
works alright
此变体和几个变体(rowwise()%>%Reduce(...)
及其他变体)失败,并显示各种错误消息:
data%>%filter(rowwise(Reduce("|", a:c)))
这个根本没有过滤,抛出“数值表达式有4个元素:只有第一个使用的”消息:
data%>%filter(Reduce("|", a:c))
我是否需要像上面那样使用mutate()创建一个新的“temp”列,然后使用filter?
对于二进制数字变量:-现在让我们假设这些逻辑变量被data_2<-data%>%mutate(across(where(is.logical), as.numeric))
强制为数字:
我试图使用rowSums()
,但也失败了:
data_2%>%rowwise()%>%mutate(abc_any=rowSums(a:c, na.rm = TRUE))
Error: Problem with `mutate()` input `abc_any`.
x 'x' must be an array of at least two dimensions
ℹ Input `abc_any` is `rowSums(a:c, na.rm = TRUE)`.
ℹ The error occured in row 1.
这些错误有哪些可能的解决方法?
Reduce
应该在list
-select
列a:c
上,并在其上使用Reduce
,因为data.frame/tibble
也是list
或者我们需要
filter
或者另一个选项是
if_any
或者从
purrr
使用reduce
或者是带有
rowSums
的代码