“ 快速对列进行数值的转换 ” 生活科学哥-R语言科学 2020-10-30 22:23 今天来分享R网友想解决一个例子,我把它进一步复杂化,与各位一起探讨,如何对于数据框中的多列进行文本型向数字型的转换;可能会有朋友说,我直接as.numberic不就行了嘛 ?设想一个具有100列的数据框,怎么办?
原始的数据
为了演示这个过程,我这里生成了一个虚拟的数据,结构如下:
library(magrittr)library(dplyr)library(stringr)dfc(df$eas.character(df$e)df$aas.character(df$a)> df a b c d e1 0.3 3 a -0.5 A2 -0.5 5 b 0.8 B3 2.4 4 c 2 C> str(df)'data.frame': 3 obs. of 5 variables: $ a: chr "0.3" "-0.5" "2.4" $ b: num 3 5 4 $ c: Factor w/ 3 levels "a","b","c": 1 2 3 $ d: Factor w/ 3 levels "-0.5","0.8","2": 1 2 3 $ e: chr "A" "B" "C"
可以看到, 在该数据中,我们生成了一个数据框,共有5列,并且是不同的格式。我们想实现的目的,就是将这些列,如果实际上是为数字的,转成数值型。在这个例子中,列a,b,d,原本应该有的归属,就是数值型;在转化的过程中,我们不用df$a
操作的思路与实现方式
整个的思路分三部分:
- 先看列中是不是已经有类型为数值型的列,如果是,就不用进行转化,如果不是,就要进行处理
- 接下来,把这些非数值型的列,分别进行判断,看看该列是不是应该属于数值,而数值,可以包含小数点,负号这两种常规符号,以及其它的0-9的数字,如果列中的所有元素满足这个要求,那就应该进行转化成数值的操作,通过该判断,来决定要转化的列;在这些列当中,考虑到非数值型的类型,还有可能是因子型,对于因子型的内容,比如说这里的d列,直接as.numberic肯定是不行的(看下面的区别),所以,保险起见,要先转化为character,再转成数值。
- 将这些要转换的列,进行直接的同步转换
#这是一个判断向量是不是非数值型,这里单独把取反写成一个函数的原因在于方便使用sapply#如果向量为非数值型,返回TRUEnotfunction(s){ return(!is.numeric(s)) }#这是对列进行预处理,把负号与.这两个数值含有的符号先除去,然后再判断有没有出现除0-9之外的符号#如果某列有任何的非数字(除点与负号之外),则返回FALSE(表示该列不需要转化)judfunction(k){ k"\\.") k"\\-") !any(grepl("\\D",k))}#将非数值型的列,先转化成字符串(防止因子型as.numberic出错)df%mutate_if(not,as.character)#直接用sapply,进行本应该是数值型的列进行as.numeric的操作(操作前df%mutate_at(colnames(df)[sapply(.,jud)],as.numeric)
最终结果可以看到,已经把a,d列进行了转换。
> df a b c d e1 0.3 3 a -0.5 A2 -0.5 5 b 0.8 B3 2.4 4 c 2.0 C> str(df)'data.frame': 3 obs. of 5 variables: $ a: num 0.3 -0.5 2.4 $ b: num 3 5 4 $ c: chr "a" "b" "c" $ d: num -0.5 0.8 2 $ e: chr "A" "B" "C"
结语
上面的例子中只是举了个简单的例子,在对于大量列的情况下转化成数值,可能 有所帮助。当然了,如果有一些缺失值的情况,也得综合加以考虑。
今天的简单分享就到这里,希望有用;另外对于dplyr包中的mutate系列的用法,可以参考一下,有些可以比较方便。
参考文献
1. https://community.rstudio.com/t/dplyr-mutate-at-with-tidyeval/20562