2014-11-25 4 views
0

중첩 된 sapply 붙여 넣기 코드를 모든 구성 요소가 non-NA인지 확인하는 ifelse()에 배치하는 문제가 발생했습니다. 사프리는 그들이 ifelse()에 없을 때 잘 작동합니다 ... 왜 이럴까요?sapply() 및 ifelse() in R

을 감안할 때 일부 매개 변수 :

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" 

, 내가 이 매개 변수가 NA하지 있는지 확인하기 위해 확인하는 ifelse()에서 동일한 코드를 넣어 경우, 출력은 다르다.

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)와 같은 것은 아닙니다. t는 이제까지 일어난다. ifelse가 더 큰 함수의 일부이기 때문에 매개 변수의 기본값이 NA가 아니기 때문에이 작업을 수행합니다. 비 NA 매개 변수의 특정 조합에는 특정 조치가 필요합니다. 예를 들어, b = NA이면 위의 코드는 ERROR를 생성해야합니다. 중첩 붙여 넣기와 조건부 검사를 모두 수행하려면 어떻게해야합니까?

+0

은 * *? 당신은 상관하지 않을 방법 ''.'을 사용하고 있습니다 ....''is.na'와 함께 사용하는''any'를 찾고 있습니까? – A5C1D2H2I1M1N2O1R2T1

+0

"a가 NA가 아니고 b가 NA가 아니고 c isn이 아닌 경우 't NA, 그런 다음 함께 붙여 넣습니다. 그렇지 않으면 오류가 발생했습니다. "더 큰 함수의 기본값 인 a, b 및 c는 NA로 기본값이 설정됩니다. 따라서 사용자가 a에 대체 값을 제공하지 않으면, b 또는 c이면! is.na (a) = FALSE – Nancy

+0

하나 이상의 벡터에 적어도 하나 이상의 'NA'가있는 값을 하나 이상 제공하고 출력을 표시하십시오. 당신의'sapply' 전화를 기대하십시오. – A5C1D2H2I1M1N2O1R2T1

답변

0

이런 상황에서 나는 ifelse을 사용하지 않고 대신 ifelse 구성 요소를 별도로 사용합니다. ifelsethis question에서 설명한 것처럼 테스트와 동일한 모양의 값만 반환합니다 (따라서 초기 출력은 3 개의 출력 만 제공함). 나는 모든 조합을 불필요한 합병증으로 보이는 정규 표현식없이 테스트 할 수있는 간결한 방법을 생각할 수 없다. 다음은 잘 작동합니다.

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" 
} 
0

ifelse는 벡터의 elementwise 검사를 수행하고, '조건'은 '다음'TRUE "또는"FALSE "이었던 특정 위치에 각각"다른 "경우에 해당하는 값을 사용한다. 당신은 위치 값에 의해 벡터의 각 부정적인 요소를 대체하기 위해, 예를 들어 ifelse을 사용할 수가 d의 첫 번째 요소로 대체되도록

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의 첫 번째 elemt이 기준을 충족하지 않습니다. 그러나 두 번째 요소는 기준을 충족하므로 두 번째 요소 인 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 세 벡터의 모든 조합을 만듭니다.적용 할 수있는 두 번째 인수로 1하고 다음 각 행에 paste을 적용하는 이유 첫 번째 차원은 모든 행을 통해 apply 실행은 (그입니다. 도움이

희망.