2017-04-11 4 views
1

내 열의 데이터 형식을 기반으로 함수를 조건부로 적용하려고하면 apply이라는 이상한 동작이 발생합니다.왜`apply` 함수가 data.frame의 숫자 형 열을 감지하고 처리 할 수 ​​없습니까?

여기에 함수가 있습니다. class()을 확인한 다음 적절한 작업을 수행합니다.

sampleF <- function(x){ 
    DT = ifelse(class(x) == "numeric" | class(x) == "integer","Numbers", 
       ifelse(class(x) == "character" | class(x) == "factor","Text","Others")) 
    return(DT) 
} 

아래의 data.frame에 적용하여 잘못된 출력을 얻으려고합니다.

df1 <- data.frame(Col1 = letters[1:5],Col2 = 1:5,Col3 = as.factor(c("A","B","A","C","A"))) 

출력 : 반면에

apply(df1,2,FUN = sampleF) 
    Col1 Col2 Col3 
    "Text" "Text" "Text" 

sapply, 제공 apply 기능의 그런 행동에 대한 이유가 무엇인지 정확한 출력

sapply(df1,sampleF) 
    Col1  Col2  Col3 
    "Text" "Numbers" "Text" 

?

답변

4

data.frame 또는 어느 정도 sapply의 열에 함수를 적용하는 경우 lapply을 사용하는 것이 더 좋습니다. 그러나 apply을 사용하면 출력이 matrix으로 강제 변환되며 단일 클래스 만 포함 할 수 있습니다. 따라서 character 요소가있는 경우 숫자 열도 character 클래스로 변환됩니다. lengthclass의 1이기 때문에, 우리는 또한 사용할 수

out <- lapply(df1, sampleF) 
unlist(out) 
# Col1  Col2  Col3 
# "Text" "Numbers" "Text" 

, if/else 또는 switch 대신 ifelse

sampleF1 <- function(x){ 
     cls <- class(x) 
     switch(cls, 
      numeric = "Numbers", 
       integer = "Numbers", 
       character = "Text", 
       factor = "Text", 
        "Others") 
} 


df2 <- cbind(df1, Col4 = TRUE) 
lapply(df2, sampleF1) 
#$Col1 
#[1] "Text" 

#$Col2 
#[1] "Numbers" 

#$Col3 
#[1] "Text" 

#$Col4 
#[1] "Others"