dplyr mutate,应用将变量(或对象,向量)合并到感兴趣的数据框之外的函数
dplyr mutate, applying functions that incorporate variables (or objects, vectors) outside the data frame of interest
问题
我很好奇如何将函数应用于 dplyr
中的 mutate
函数,这需要一个参数,该参数是我在别处定义的向量。
我有一个示例,它从我实际尝试做的事情中抽象出来(我正在使用多个列,检查该行的那些列中是否存在值取决于 [=48 的日期=],然后 return 一个字符串分类),但是为了简洁起见,下面的示例会产生相同的错误,但愿它足够了。
设置
DF <- data.frame(
Index = 1:100,
Num1 = runif(100,0,100) %/% 1
)
# array to check
CheckArray = seq(0,100, by = 2)
f <- function(x, ArrayToCheck){
if (x %in% ArrayToCheck){
return(T)
} else {
return(F)
}
}
我的尝试
DF <- dplyr::mutate(
DF,
Num1_even = f(Num1, CheckArray)
)
这当然是 return 一个错误
Warning message:
In if (x %in% ArrayToCheck) { :
the condition has length > 1 and only the first element will be used*
补充说明
我应该指出,我知道我的示例可以在没有函数的情况下通过其他方式解决,例如
dplyr::mutate(
DF,
Num1_even = Num1 %in% CheckArray
)
或
dplyr::mutate(
DF,
Num1_even = Num1 %in% seq(0,100, by = 2)
)
但在这种情况下和许多其他情况下,我经常发现在我的 DF 之外定义一个向量很有价值,然后将一个函数与多个附加参数一起应用于每一行。
我也看到通过 apply 函数族解决了这个问题,但我希望 dplyr
中有一个方法,因为它是如此之快并且具有如此好的语法。
也许我们可以让 Hadleyverse 添加一个运算符,告诉 dplyr
跳出当前 data.frame 的范围,例如
CheckArray = seq(0,100, by = 2)
DF <- dplyr::mutate(
DF,
Num1_even = f(Num1, %o%CheckArray%o%)
)
这与CheckArray
向量无关。问题是 if
语句在 R
中没有向量化。您可以改用 ifelse
。然后你的电话应该工作。查看 ?ifelse
了解更多信息。
f <- function(x, ArrayToCheck){
ifelse(x %in% ArrayToCheck, TRUE, FALSE)
}
dplyr::mutate(
DF,
Num1_even = f(Num1, CheckArray)
)
当然在这种情况下 ifelse
实际上也不需要(见下文)。如果您想要的输出仅包含 TRUE
和 FALSE
,您可以跳过 ifelse
,但我添加了 ifelse
以防您的实际示例比这更复杂。
f <- function(x, ArrayToCheck){
x %in% ArrayToCheck
}
问题
我很好奇如何将函数应用于 dplyr
中的 mutate
函数,这需要一个参数,该参数是我在别处定义的向量。
我有一个示例,它从我实际尝试做的事情中抽象出来(我正在使用多个列,检查该行的那些列中是否存在值取决于 [=48 的日期=],然后 return 一个字符串分类),但是为了简洁起见,下面的示例会产生相同的错误,但愿它足够了。
设置
DF <- data.frame(
Index = 1:100,
Num1 = runif(100,0,100) %/% 1
)
# array to check
CheckArray = seq(0,100, by = 2)
f <- function(x, ArrayToCheck){
if (x %in% ArrayToCheck){
return(T)
} else {
return(F)
}
}
我的尝试
DF <- dplyr::mutate(
DF,
Num1_even = f(Num1, CheckArray)
)
这当然是 return 一个错误
Warning message: In if (x %in% ArrayToCheck) { : the condition has length > 1 and only the first element will be used*
补充说明
我应该指出,我知道我的示例可以在没有函数的情况下通过其他方式解决,例如
dplyr::mutate(
DF,
Num1_even = Num1 %in% CheckArray
)
或
dplyr::mutate(
DF,
Num1_even = Num1 %in% seq(0,100, by = 2)
)
但在这种情况下和许多其他情况下,我经常发现在我的 DF 之外定义一个向量很有价值,然后将一个函数与多个附加参数一起应用于每一行。
我也看到通过 apply 函数族解决了这个问题,但我希望 dplyr
中有一个方法,因为它是如此之快并且具有如此好的语法。
也许我们可以让 Hadleyverse 添加一个运算符,告诉 dplyr
跳出当前 data.frame 的范围,例如
CheckArray = seq(0,100, by = 2)
DF <- dplyr::mutate(
DF,
Num1_even = f(Num1, %o%CheckArray%o%)
)
这与CheckArray
向量无关。问题是 if
语句在 R
中没有向量化。您可以改用 ifelse
。然后你的电话应该工作。查看 ?ifelse
了解更多信息。
f <- function(x, ArrayToCheck){
ifelse(x %in% ArrayToCheck, TRUE, FALSE)
}
dplyr::mutate(
DF,
Num1_even = f(Num1, CheckArray)
)
当然在这种情况下 ifelse
实际上也不需要(见下文)。如果您想要的输出仅包含 TRUE
和 FALSE
,您可以跳过 ifelse
,但我添加了 ifelse
以防您的实际示例比这更复杂。
f <- function(x, ArrayToCheck){
x %in% ArrayToCheck
}