我遇到了将嵌套的sapply粘贴代码包装到ifelse()中的问题,该问题检查所有组件是否为非NA。当他们不在ifelse()时,sapply工作得很好......为什么会这样?
给出一些参数:
a = c(1, 2, 3)
b = c("a", "b")
c = c("X", "Y")
以下是我如何设法将所有组合粘贴在一起
as.vector(sapply(sapply(a, function(x){paste(x, b, sep = "")}),
function(x){paste(x, c, sep = "")}))
输出就是这个。这正是我想要的:
[1] "1aX" "1aY" "1bX" "1bY" "2aX" "2aY" "2bX" "2bY" "3aX" "3aY" "3bX" "3bY"
但是,如果我将完全相同的代码放在ifelse()中,检查以确保参数不是NA,则输出不同。
ifelse(!is.na(a) & !is.na(b) & !is.na(c),
as.vector(sapply(sapply(a, function(x){paste(x, b, sep = "")}),
function(x){paste(x, c, sep = "")})), "Error")
[1] "1aX" "1aY" "1bX"
Warning messages:
1: In !is.na(a) & !is.na(b) :
longer object length is not a multiple of shorter object length
2: In !is.na(a) & !is.na(b) & !is.na(c) :
longer object length is not a multiple of shorter object length
为什么呢?很明显a,b和c的长度不同;我不明白为什么这在ifelse()中很重要。为了澄清,!is.na()正在检查整个向量是否为NA,而不是像c(1,NA,3)那样,因为我将使用代码在一个不会发生的环境中。我这样做是因为ifelse是较大功能的一部分,其中参数默认为NA;非NA参数的某些组合需要特定动作。例如,如果b = NA,则上面的代码应该产生ERROR。如何完成嵌套粘贴和条件检查?
答案 0 :(得分:0)
老实说,在这种情况下,我不会使用ifelse
而是分别使用if
和else
组件。 ifelse
仅返回与测试形状相同的值(因此您的初始输出仅提供3个输出),如this question中所述。我想不出简洁的方法来获得所有组合测试没有一些正则表达式,这似乎只是一个不必要的复杂功能。以下应该可以正常工作。
if(!any(is.na(c(a,b,c)))){
as.vector(sapply(sapply(a, function(x){paste(x, b, sep = "")}),
function(x){paste(x, c, sep = "")}))
}else{
"Error"
}
答案 1 :(得分:0)
ifelse
对向量进行元素检查,并在'condition'分别为'TRUE'或'FALSE'分别为'then'和'else'的特定位置使用相应的值。例如,您可以使用ifelse
以位置值替换向量中的每个否定元素:
d <- c(1, -1, 2, -2, 3, -3)
order <- seq_along(d)
ifelse(d < 0, order, d)
# [1] 1 2 2 4 3 6
因此d
的第一个元素不符合标准,因此它被d
的第一个元素替换。然而,第二个元素符合标准,因此它被order
的第二个元素替换,依此类推。这就是为什么所有向量应该具有相同的长度,如果没有,R
使用其回收技术。
所以你想要做的是使用一个简单的if
语句
a <- c(1, 2, 3)
b <- c("a", "b")
d <- c("X", "Y")
if (all(!is.na(c(a, b, d))))
as.vector(sapply(sapply(a, function(x){paste(x, b, sep = "")}),
function(x) {paste(x, d, sep = "")})) else
"Error"
# [1] "1aX" "1aY" "1bX" "1bY" "2aX" "2aY" "2bX" "2bY" "3aX" "3aY" "3bX" "3bY"
d <- NA
if (all(!is.na(c(a, b, d))))
as.vector(sapply(sapply(a, function(x){paste(x, b, sep = "")}),
function(x) {paste(x, d, sep = "")})) else
"Error"
# [1] "Error"
但是,您的代码难以阅读,您可以通过以下代码提高可读性:
a <- c(1, 2, 3)
b <- c("a", "b")
d <- c("X", "Y")
if (all(!is.na(c(a, b, d)))) apply(expand.grid(a, b, d), 1, paste, collapse = "") else "Error"
# [1] "1aX" "2aX" "3aX" "1bX" "2bX" "3bX" "1aY" "2aY" "3aY" "1bY" "2bY" "3bY"
d <- NA
if (all(!is.na(c(a, b, d)))) apply(expand.grid(a, b, d), 1, paste, collapse = "") else "Error"
# [1] "Error"
expand.grid
创建三个向量的所有组合。 apply
遍历所有行(这是第一个维度,这就是1
作为第二个参数应用然后将paste
应用于每一行的原因。
希望有所帮助。