sapply和apply使用is.character()给出不同的结果

时间:2017-02-26 10:37:40

标签: r character apply

我试图将我的数据框的特征转换为类型字符的特征并找到这篇文章:
tolower
我在几个data.frames上构建了一个函数,最后发现我的所有特性都被视为字符!

mytolower <- function(p_vector){
  if (is.character(p_vector)) return(tolower(iconv(enc2utf8(p_vector), sub = "byte")))
  else return(p_vector)
}
for (df in c("train", "test")) as.data.frame(apply(get(df), 2, function(x) mytolower(x)), stringsAsFactors = FALSE)

在Stackoverflow上看起来更好,我发现第二篇文章通过使用lapply部分地解决了这个问题,但是奇怪地建议以类似的方式应用和sapply工作
lapply rather than apply
因此,我最终构建了这个基本上说明我的麻烦的例子:

train <- data.frame(v1=1:3, v2=c("a","b","c"), v3=11:13, stringsAsFactors = FALSE)
str(train)
apply(train, 2, function(x) is.character(x)) #wrong
lapply(train, function(x) is.character(x)) #right
sapply(train, function(x) is.character(x)) #right
sapply(train, is.character) #right

虽然apply会将所有功能视为“character”,lapply或sapply将能够区分数字和字符功能。为什么会这样?有没有办法让申请找到正确的答案? 感谢

2 个答案:

答案 0 :(得分:2)

在应用is.character()之前,train首先被强制转换为矩阵。由于矩阵仅包含单个类型的对象,因此所有元素都成为字符串。

来自apply()的帮助文件:

“如果X不是数组而是具有非空昏暗值的类的对象(例如数据框),则应用尝试通过as.matrix将其强制转换为数组(如果它是二维的)(例如,数据框)或通过as.array。“

我建议使用mutate_if()中的dplyr函数。

library(dplyr)
mutate_if(train, is.character, toupper)

#    v1 v2 v3
#    1  1  A 11
#    2  2  B 12
#    3  3  C 13

答案 1 :(得分:0)

apply函数需要一个矩阵或数组作为它的输入,它强制转换你正在为它提供的数据帧,并且as.matrix()转换将所有数组转换为一个字符数组,因为所有列都是字符类型。