R语言因子类型的实现
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1.因子</li><li>2.table() 函数</li><li>3.tapply() 函数</li><li>4.forcats 包的因子函数</li></ul></div><p class="maodian"></p><h2>1.因子</h2><p> R 中用<strong>因子代表数据中分类变量</strong> , 如性别、省份、职业。有<strong>序因子代表有序量度</strong>,如打分结果,疾病严重程度等。</p>
<p> 用 <strong>factor() </strong> 函数把<strong>字符型向量转换成因子</strong>,如</p>
<div class="jb51code"><pre class="brush:plain;">x <- c(" 男", " 女", " 男", " 男", " 女")
sex <- factor(x)
sex</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="47" src="https://img.jbzj.com/file_images/article/202203/20220304110637195.png" width="402" /></p>
<div class="jb51code"><pre class="brush:plain;">attributes(sex)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="102" src="https://img.jbzj.com/file_images/article/202203/20220304110637196.png" width="404" /></p>
<p> 因子有<strong> </strong><strong>class </strong><strong>属性</strong>,取值为"<strong>factor</strong>",还有一个 <strong>levels(水平值) </strong><strong>属性</strong>,此属性可以用 <strong>levels()</strong> 函数访问,如</p>
<div class="jb51code"><pre class="brush:plain;">levels(sex)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="22" src="https://img.jbzj.com/file_images/article/202203/20220304110637197.png" width="518" /></p>
<p><strong>因子的 levels </strong> <strong>属性可以看成是一个映射</strong>,把整数值 1,2, . . . 映射成这些水平值,因子在保存时会保存成整数值 1,2, . . . 等与水平值对应的编号。这样可以节省存储空间,在建模计算的程序中也比较有利于进行数学运算。</p>
<p>事实上,<strong>read.csv() </strong> 函数的默认操作会把<strong>输入文件的字符型列自动转换成因子</strong>,这对于性别、职业、地名这样的列是<strong>合适</strong>的,但是对于姓名、日期、详细地址这样的列则<strong>不合适</strong>。所以,在 read.csv() 调用中经常加选项 stringsAsFactors=FALSE 选项禁止这样的自动转换,还可以用 <strong>colClasses </strong>选项逐个指定每列的类型。</p>
<p> 用 <strong>as.numeric()</strong> 可以把<strong>因子转换为纯粹的整数值</strong>,如</p>
<div class="jb51code"><pre class="brush:plain;">as.numeric(sex)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="21" src="https://img.jbzj.com/file_images/article/202203/20220304110637198.png" width="440" /></p>
<p>因为<strong>因子实际保存为整数值</strong>,所以对因子进行一些字符型操作可能导致错误。用 <strong>as.character() </strong>可以把<strong>因子转换成原来的字符型</strong>,如</p>
<div class="jb51code"><pre class="brush:plain;">as.character(sex)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="27" src="https://img.jbzj.com/file_images/article/202203/20220304110637199.png" width="583" /></p>
<p>为了<strong>对因子执行字符型操作(如取子串)</strong>,保险的做法是先用 <strong>as.character()</strong> 函数<strong>强制转换</strong>为字符型。</p>
<p><strong>factor() 函数的一般形式</strong>为</p>
<div class="jb51code"><pre class="brush:plain;">factor(x, levels = sort(unique(x), na.last = TRUE),
labels, exclude = NA, ordered = FALSE)</pre></div>
<p>可以用<strong>选项 </strong> <strong>levels 自行指定各水平值</strong> , 不指定时由 x 的不同值来求得。可以用<strong>选项 labels </strong> <strong>指定各水平的标签</strong> , 不指定时用各水平值的对应字符串。可以用 <strong>exclude </strong> <strong>选项</strong>指定要转换为缺失值 (NA) 的元素值集合。如果<strong>指定了 levels</strong>, 则当自变量 x 的某个元素等于第 j 个水平值时输出的因子对应元素值取整数 j, 如果该 <strong>元素值没有出现</strong>在 levels 中则输出的因子对应元素值取NA。 <strong>ordered 取真值时</strong>表示因子水平是有次序的 (按编码次序)。</p>
<p>在使用 <strong>factor() </strong> <strong>函数定义因子时</strong>,如果知道自变量元素的所有可能取值,应尽可能使用 <strong>levels= </strong> <strong>参数指定这些不同可能取值</strong>,这样,即使某个取值没有出现,此变量代表的含义和频数信息也是完整的。自己<strong>指定 levels= </strong> <strong>的另一好处</strong>是可以按正确的次序显示因子的分类统计值。</p>
<p>因为一个<strong>因子的 levels </strong> <strong>属性是该因子独有</strong>的,所以<strong>合并两个因子</strong>有可能造成<strong>错误</strong>,但在最新版本4.1.2 没有报错,应跟版本有关,如</p>
<div class="jb51code"><pre class="brush:plain;">li1 <- factor(c(' 男', ' 女'))
li2 <- factor(c(' 男', ' 男'))
c(li1, li2)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="39" src="https://img.jbzj.com/file_images/article/202203/20220304110637200.png" width="636" /></p>
<p>如果结果不是因子的话,需要对其进行转换。则那样<strong>正确的做法</strong>是</p>
<div class="jb51code"><pre class="brush:plain;">factor(c(as.character(li1), as.character(li2)))</pre></div>
<p>就是先转换为字符型,再进行合并就可以了。</p>
<p class="maodian"></p><h2>2.<strong>table() </strong>函数</h2>
<p> 用 <strong>table() </strong> 函数<strong>统计因子各水平的出现次数</strong>(称为频数或频率)。也可以对一般的向量统计每个不同元素的出现次数。如</p>
<div class="jb51code"><pre class="brush:plain;">x <- c(" 男", " 女", " 男", " 男", " 女")
sex <- factor(x)
table(sex)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="59" src="https://img.jbzj.com/file_images/article/202203/20220304110637201.png" width="415" /></p>
<p>对一个变量用<strong> </strong> <strong>table </strong> <strong>函数计数的结果是一个特殊的有元素名的向量</strong>,元素名是自变量的不同取值,结果的元素值是对应的频数。单个因子或单个向量的频数结果可以用向量的下标访问方法取出单个频数或若干个频数的子集。</p>
<p class="maodian"></p><h2>3.tapply() 函数</h2>
<p>可以<strong>按照因子分组然后每组计算另一变量的概括统计</strong>。如</p>
<div class="jb51code"><pre class="brush:plain;">x <- c(" 男", " 女", " 男", " 男", " 女")
sex <- factor(x)
h <- c(165, 170, 168, 172, 159)
tapply(h, sex, mean)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="41" src="https://img.jbzj.com/file_images/article/202203/20220304110637202.png" width="473" /></p>
<p class="maodian"></p><h2>4.forcats<strong> </strong>包的因子函数</h2>
<p>如果使用此函数,需要先进行载入:</p>
<div class="jb51code"><pre class="brush:plain;">library(forcats)</pre></div>
<p> 在<strong>分类变量类数较多时</strong>,往往需要对因子水平另外排序、合并等,forcats 包提 供了一些针对因子的方便函数。</p>
<p> <strong>orcats::fac_reorder()</strong> 可以根据不同因子水平分成的组中另一数值型变 量的<strong>统计量值排序</strong>。如:</p>
<div class="jb51code"><pre class="brush:plain;">set.seed(1)
fac <- sample(c("red", "green", "blue"), 30, replace=TRUE)
fac <- factor(fac, levels=c("red", "green", "blue"))
x <- round(100*(10+rt(30,2)))
res1 <- tapply(x, fac, sd); res1</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="44" src="https://img.jbzj.com/file_images/article/202203/20220304110637203.png" width="524" /></p>
<p> 对上面数值<strong>画条形图</strong>:</p>
<div class="jb51code"><pre class="brush:plain;">barplot(res1)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="505" src="https://img.jbzj.com/file_images/article/202203/20220304110637204.png" width="470" /></p>
<p> 如果希望<strong>按照统计量次序对因子排序</strong>,可以用 <strong>forcats::fct_reorder()</strong> 函数,并画图条形图,如</p>
<div class="jb51code"><pre class="brush:plain;">fac2 <- fct_reorder(fac, x, sd)
res2 <- tapply(x, fac2, sd)
barplot(res2)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="524" src="https://img.jbzj.com/file_images/article/202203/20220304110637205.png" width="668" /></p>
<p> 新的因子 fac2 的因子水平次序已经<strong>按照变量 </strong><strong>x </strong><strong>的标准差从小到大排列</strong>。</p>
<p> 有时在<strong>因子水平数较多</strong>时仅想将特定的一个或几个水平次序放到因子水平最前面,可以用 <strong>forcats::fct_relevel()</strong> 函数,如:</p>
<div class="jb51code"><pre class="brush:plain;">levels(fac)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="26" src="https://img.jbzj.com/file_images/article/202203/20220304110637206.png" width="416" /></p>
<div class="jb51code"><pre class="brush:plain;">fac3 <- fct_relevel(fac, "blue"); levels(fac3)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="26" src="https://img.jbzj.com/file_images/article/202203/20220304110638207.png" width="478" /></p>
<p><strong>fct_relevel() </strong> <strong>第一个参数</strong>是要<strong>修改次序</strong>的因子,后续可以有多个字符型参数表示要提前的水平。</p>
<p><strong>forcats::fct_reorder2(f, x, y)</strong> 也<strong>调整因子 </strong> <strong>f </strong> <strong>的水平的次序</strong>,但是根据与每组中最大的 x 值相对应的 y 值大小调整次序,这样在作多个因子水平对应的曲线图时可以比较容易地区分多条曲线。</p>
<p> <strong>forcats::fct_recode() </strong>可以<strong>修改每个水平的名称</strong>,如:</p>
<div class="jb51code"><pre class="brush:plain;">fac4 <- fct_recode(
fac,
" 红"="red", " 绿"="green", " 蓝"="blue")
table(fac4)</pre></div>
<p>返回:</p>
<p style="text-align:center"><img alt="" height="62" src="https://img.jbzj.com/file_images/article/202203/20220304110638208.png" width="462" /></p>
<p> <strong> fct_recode() </strong>在修<strong>改水平名时允许多个旧水平对应到一个新水平</strong>,从而合并原来的水平。如果<strong>合并很多</strong>,可以用 <strong>fct_collapse() </strong>函数,记得要先导入<strong>forcats </strong> 包的因子函数,如</p>
<div class="jb51code"><pre class="brush:plain;">compf <- fct_collapse(
comp,
" 其它"=c("", " 无名", " 无应答"),
" 联想"=c(" 联想", " 联想集团"),
" 百度"=c(" 百度", " 百度集团") )</pre></div>
<p>如果某个因子频数少的水平很多,在统计时有过多水平不易展示主要的类别,可以用 <strong>forcats::fct_lump(f) </strong> <strong>合并</strong>,缺省地从最少的类合并一直到 “ 其它 ” 类超过其它最小的类之前,可以用 <strong>n= </strong> <strong>参数指定要保留多少个类</strong>。</p>
<p>练习</p>
<p>设文件 class.csv 中包含如下内容 :<br />name,sex,age,height,weight<br />Alice,F,13,56.5,84<br />Becka,F,13,65.3,98<br />Gail,F,14,64.3,90<br />Karen,F,12,56.3,77<br />Kathy,F,12,59.8,84.5<br />Mary,F,15,66.5,112<br />Sandy,F,11,51.3,50.5<br />Sharon,F,15,62.5,112.5<br />Tammy,F,14,62.8,102.5<br />Alfred,M,14,69,112.5<br />Duke,M,14,63.5,102.5<br />Guido,M,15,67,133<br />James,M,12,57.3,83<br />Jeffrey,M,13,62.5,84<br />John,M,12,59,99.5<br />Philip,M,16,72,150<br />Robert,M,12,64.8,128<br />Thomas,M,11,57.5,85<br />William,M,15,66.5,112<br />用如下程序把该文件读入为 R 数据框 d.class, 其中的 sex 列已经自动转换为因<br />子。取出其中的 sex 和 age 列到变量 sex 和 age 中</p>
<div class="jb51code"><pre class="brush:plain;">d.class <- read.csv('class.csv', header=TRUE)
sex <- d.class[,'sex']
age <- d.class[,'age']</pre></div>
<p>(1) 统计并显示列出 sex 的不同值频数;</p>
<p>(2) 分男女两组分别求年龄最大值;</p>
<p>(3) 把 sex 变量转换为一个新的因子, F 显示成 “Female” , M 显示成 “Male” 。</p>
<p>到此这篇关于R语言因子类型的实现的文章就介绍到这了,更多相关R语言因子类型内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>R语言批量读取某路径下文件内容的方法</li><li>R语言向量下标和子集的使用</li><li>基于R语言 数据检验详解</li><li>R语言使用cgdsr包获取TCGA数据示例详解</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]