将变量从字符转换为数字,但不包括一个字符变量

时间:2017-05-24 06:35:12

标签: r dataframe char type-conversion

问题

使用R中的数据框,我想将表示为字符的变量更改为表示为数字的变量(即从类chrnum)。

对于整个数据集,这是一个简单的问题(不同类型的解决方案herehereherehere)。但是,我有一个变量需要保留为字符。

示例数据

使用此示例数据(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]

问题

  • 将数据框的字符变量转换为数字,同时排除指定的子集的最佳解决方案是什么?
  • 我的哪些尝试是正确的道路,还是有更好的方法?
  • [奖励]什么机制导致[a]和[b]上方的意外结果?

1 个答案:

答案 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)applydata.frame转换为matrixmatrix只能容纳一个class。假设character中有一个matrix元素,它会将整体转换为character

2)将as.numericapply一起使用是有问题的,因为'chrOK'已经是character类列。每当as.numeric应用于非数字字符串时,它就会将其转换为NA。

3)OP在第二种方法中使用了相同的apply。它描述如1。