sapply 和 apply 使用 is.character() 给出不同的结果
sapply and apply give different results with is.character()
我试图转换以降低我的数据框的字符类型的特征,并发现了这个 post:
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)
在 Whosebug 上看起来更好,我发现第二个 post 通过使用 lapply 部分解决了问题,但奇怪的是,它暗示 apply 和 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 将能够区分数字和字符特征。为什么会这样?有没有办法让 apply 找到正确的答案?
谢谢
在应用 is.character()
之前,首先将 train
强制转换为矩阵。由于矩阵只包含单一类型的对象,因此所有元素都变成字符串。
来自 apply()
的帮助文件:
If X is not an array but an object of a class with a non-null dim value (such as a data frame), apply attempts to coerce it to an array via as.matrix if it is two-dimensional (e.g., a data frame) or via as.array.
我建议使用 dplyr
中的 mutate_if()
函数。
library(dplyr)
mutate_if(train, is.character, toupper)
# v1 v2 v3
# 1 1 A 11
# 2 2 B 12
# 3 3 C 13
apply 函数需要一个矩阵或数组作为输入,它会强制转换您提供给它的数据帧,并且 as.matrix() 转换会将所有数组转换为字符数组,因为所有列都将到来出来是字符型的。
我试图转换以降低我的数据框的字符类型的特征,并发现了这个 post:
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)
在 Whosebug 上看起来更好,我发现第二个 post 通过使用 lapply 部分解决了问题,但奇怪的是,它暗示 apply 和 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 将能够区分数字和字符特征。为什么会这样?有没有办法让 apply 找到正确的答案? 谢谢
在应用 is.character()
之前,首先将 train
强制转换为矩阵。由于矩阵只包含单一类型的对象,因此所有元素都变成字符串。
来自 apply()
的帮助文件:
If X is not an array but an object of a class with a non-null dim value (such as a data frame), apply attempts to coerce it to an array via as.matrix if it is two-dimensional (e.g., a data frame) or via as.array.
我建议使用 dplyr
中的 mutate_if()
函数。
library(dplyr)
mutate_if(train, is.character, toupper)
# v1 v2 v3
# 1 1 A 11
# 2 2 B 12
# 3 3 C 13
apply 函数需要一个矩阵或数组作为输入,它会强制转换您提供给它的数据帧,并且 as.matrix() 转换会将所有数组转换为字符数组,因为所有列都将到来出来是字符型的。