R语言——判断向量是分类还是连续数值

昨天做完信息熵计算之后,想到了一个问题

一般我们用read.csv读取一个表格时,R软件自动判断转换出来的分类型变量好像经常性的对不上我们的认知,大概举个例子:

比如我现在读取了一张表,没附加参数,由R自行判断哪些列可以作为分类变量转成因子型

在它读取完之后,我看了看它的转化结果,然后在图的左边添了一列圈圈叉叉

其中×的那两排,就是我的认知跟它有分歧的地方(表格总共9列)

R语言——判断向量是分类还是连续数值

这正确率还真是不太高,难怪很多书上都推荐加stringsAsFactor参数

但是,如果是个列数很多的大表格,我不用眼睛去人工判断的话,有可能让R软件尽量自己分正确嘛?

然后,我萌生了做个表格转换function的想法,并成功地把自己坑到了晚上10点还在整代码的境地

从数学角度来说,判断是否分类变量的依据大概是这样的:

我们先计算出表中每列向量的熵值,由于这里全部是单向量输入,所以弄了个简化版(跟昨天相比的话)

R语言——判断向量是分类还是连续数值

按照熵的性质,其取值范围是个介于[0,log2(n)]的值,其中n为向量长度,那就是说,如果我把所有熵值都除以它的最大值,就可以统一转换成一个0到1之间的量度了吧

R语言——判断向量是分类还是连续数值

算出比值后对照下我认知中的分类变量,可以看到符合要求的分类变量熵值都比较小,那怎么判断分类和连续的中间节点呢,这时我想到要不画个图看看

R语言——判断向量是分类还是连续数值

当用diff函数做一阶差分后,感觉已经看到了胜利的曙光,咱要的分界节点就是一阶差分的最大值,排在他前边的判断为分类项,在它本身和它之后的判断为连续值

PS:diff做完会把向量剪短一个,所以做之前先多补了一个最小值进去

R语言——判断向量是分类还是连续数值

当数学部分差不多搞定后,我发现了另一个蛋疼的问题,那就是从来可以应对大部分循环结构的apply函数,失效了

是的,由于它在拆解二维表到向量的过程中已经内部转换了一次向量格式到文本型,以至于它碰到所有判断向量格式的函数一律回答character,所以,我默默地打开帮助文档去捡回了丢弃已久的for函数

R语言——判断向量是分类还是连续数值

最终整理出来的完整代码如下:

#单列熵值计算
En1 Pi En return(En) }
#判断向量为分类还是连续
GCconvert if (!is.data.frame(x)){
stop("'x' must be data.frame") }
else{
Pi names(Pi) D1 Gcols for (i in 1:ncol(x)) {
if(is.factor(x[,i])) {
x[,i] }
for (j in Gcols) {
x[,j] }
return(x) }

当中为了避免表中已有被错转成因子型的列,增加了一段for循环转成文本

R语言——判断向量是分类还是连续数值

代进去试下效果

R语言——判断向量是分类还是连续数值

嗯,有前途,后边可以再多试几个表看看 : )


分享到:


相關文章: