问题
使用R中的数据框,我想将表示为字符的变量更改为表示为数字的变量(即从类chr
到num
)。
对于整个数据集,这是一个简单的问题(不同类型的解决方案here,here,here和here)。但是,我有一个变量需要保留为字符。
示例数据
使用此示例数据(df
),假设我想仅将var1
从班级chr
更改为num
,将"chrOK"
保留为{ {1}}变量。在我的真实数据集中,有许多变量需要更改,因此像chr
这样的手动方法过于费力。
df$var1 = as.numeric(df$var1)
部分解决方案
我尝试了几种似乎很接近的方法,但并没有完全按照我的意愿行事。
尝试1 - 介绍NAs
我的大多数列都应该是数字字符,例如df = data.frame(var1 = c("1","2","3","4"),
var2 = c(1,2,3,4),
chrOK = c("rick", "summer","beth", "morty"),
stringsAsFactors = FALSE)
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : chr "1" "2" "3" "4"
$ var2 : num 1 2 3 4
$ chrOK: chr "rick" "summer" "beth" "morty"
。因此,使用"var1"
转换类工作。但是,此方法失败会导致apply()
中的NA
值。
"chrOK"
尝试2 - 拆分,转换,cbind
在df = as.data.frame(apply(df, 2, function(x) as.numeric(x)))
Warning message:
In FUN(newX[, i], ...) : NAs introduced by coercion
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : num 1 2 3 4
$ var2 : num 1 2 3 4
$ chrOK: num NA NA NA NA
变量的子集上使用apply()
,不包括chr
,不会导致"chrOK"
,但需要使用NA
重新包含cbind()
"chrOK"
。
此解决方案并不理想,因为cbind()
结果很难检查数据突变。 (另外,"chrOK"
作为一个因素返回。使用df = cbind(changed,as.character(unchanged))
不起作用。[a])
changed = as.data.frame(apply(df[-(which(colnames(df)=="chrOK"))],2,function(x) as.numeric(x)))
unchanged = (df$chrOK)
df = cbind(changed,unchanged)
str(df)
'data.frame': 4 obs. of 3 variables:
$ var1 : num 1 2 3 4
$ var2 : num 1 2 3 4
$ unchanged: Factor w/ 4 levels "beth","morty",..: 3 4 1 2 #[a]
尝试3 - 正确的子集,但转换时出错
使用setdiff()
我得到chr
类变量的子集,不包括`“chrOK”。
df[setdiff(names(df[sapply(df,is.character)]),"chrOK")]
var1
1 1
2 2
3 3
4 4
但是尝试将其插入应用函数,以便只有子集从chr
更改为num
才会返回错误(请参阅[b])。
apply(as.numeric(df[setdiff(names(df[sapply(df,is.character)]),"chrOK")]),
2,function(x) as.numeric(x))
Error in apply(as.numeric(df[setdiff(names(df[sapply(df, is.character)]), :
(list) object cannot be coerced to type 'double' #[b]
问题
答案 0 :(得分:2)
我们可以使用type.convert
中的base R
循环遍历数据集的列并将其分配回原始对象
df[] <- lapply(df, function(x) type.convert(as.character(x), as.is = TRUE))
str(df)
#'data.frame': 4 obs. of 3 variables:
#$ var1 : int 1 2 3 4
#$ var2 : int 1 2 3 4
#$ chrOK: chr "rick" "summer" "beth" "morty"
type.convert
正在调用C代码,即C_typeconvert
OP解决方案获得NAs的原因是
1)apply
将data.frame
转换为matrix
,matrix
只能容纳一个class
。假设character
中有一个matrix
元素,它会将整体转换为character
。
2)将as.numeric
与apply
一起使用是有问题的,因为'chrOK'已经是character
类列。每当as.numeric
应用于非数字字符串时,它就会将其转换为NA。
3)OP在第二种方法中使用了相同的apply
。它描述如1。