为什么`apply`函数无法检测并处理data.frame的数字列?

时间:2017-04-11 09:50:21

标签: r apply sapply

当我尝试根据列的数据类型有条件地应用函数时,apply会出现奇怪的行为。

这是功能。它检查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提供正确的输出

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

apply函数的这种行为可能是什么原因?

1 个答案:

答案 0 :(得分:4)

最好使用data.framesapply或某种程度apply的列上应用函数。但是,对于matrix,它会将输出强制转换为character,并且它只能包含一个类。因此,如果有任何character元素,即使数字列也会转换为out <- lapply(df1, sampleF) unlist(out) # Col1 Col2 Col3 # "Text" "Numbers" "Text" 类。

length

此外,由于class的{​​{1}}为1,我们可以使用if/elseswitch代替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"