更改因子中特定级别的名称

时间:2015-01-07 14:47:04

标签: r dataframe categorical-data

我正在处理的数据框包含许多因素。从mtcars (cyl, vs, am, gear, carb)中获取分类变量。

head(mtcars[c("cyl","vs","am","gear","carb")])
                  cyl vs am gear carb
Mazda RX4           6  0  1    4    4
Mazda RX4 Wag       6  0  1    4    4
Datsun 710          4  1  1    4    1
Hornet 4 Drive      6  1  0    3    1
Hornet Sportabout   8  0  0    3    2
Valiant             6  1  0    3    1

目前我有两个嵌套的for循环来提取那些在特定因子中发生的时间少于10%的级别并将其分配给新的级别名称。所以我想将这些因素中的levsl分配给一个名为guz的新关卡。有没有优雅的wqy呢?

输出将是一个数据帧,其中对于everz因子(假设数据集中的cols是因子)属于发生少于10个时间的级别的那些行被归为新级别guz。在碳水化合物中取2级...它只发生一次(好的超过10%,但只是想象就是这种情况)然后在这个fdactor(以及其中所有其他级别,因为这是因素)进入一个新的水平名称guz。然后新的碳氢化合物柱将是4,4,1,1,guz,1。

50%阈值的输出将是

head(mtcars[c("cyl","vs","am","gear","carb")])
                  cyl vs am gear carb
Mazda RX4           6  0  1    4    guz
Mazda RX4 Wag       6  0  1    4    guz
Datsun 710          guz  1  1    4    1
Hornet 4 Drive      6  1  0    3    1
Hornet Sportabout   guz  0  0    3    guz
Valiant             6  1  0    3    1

1 个答案:

答案 0 :(得分:2)

首先,让mtcars中的列成为明确因素:

cols = c("vs","am","gear","cyl", "carb")
for(col in cols){mtcars[,col]=factor(paste0(col,mtcars[,col]))}

现在编写一个函数,该函数接受一个因子并返回一个因子级别重新分类的因子。使标签和阈值变得灵活:

thresh_factor = function(F, thresh=0.1, label="guz"){
         n=length(F)
         t=table(F)
         under=t<(n*thresh)
         levels(F)[under]=label
         F}

现在可以测试:

> thresh_factor(factor(1:20))
 [1] guz guz guz guz guz guz guz guz guz guz guz guz guz guz guz guz guz guz guz
[20] guz
Levels: guz

它们都变为guz,因为1:20中的每一个都是唯一的。更多测试:

> thresh_factor(mtcars$carb)
 [1] carb4 carb4 carb1 carb1 carb2 carb1 carb4 carb2 carb2 carb4 carb4 guz  
[13] guz   guz   carb4 carb4 carb4 carb1 carb2 carb1 carb1 carb2 carb2 carb4
[25] carb2 carb1 carb2 carb2 carb4 guz   guz   carb2
Levels: carb1 carb2 guz carb4

其中一些级别已被替换。另一个测试:

> thresh_factor(mtcars$cyl)
 [1] cyl6 cyl6 cyl4 cyl6 cyl8 cyl6 cyl8 cyl4 cyl4 cyl6 cyl6 cyl8 cyl8 cyl8 cyl8
[16] cyl8 cyl8 cyl4 cyl4 cyl4 cyl4 cyl8 cyl8 cyl8 cyl8 cyl4 cyl4 cyl4 cyl8 cyl6
[31] cyl8 cyl4
Levels: cyl4 cyl6 cyl8

其中没有一个被替换。看起来不错。现在对所有列进行操作:

> for(col in cols){mtcars[,col]=thresh_factor(mtcars[,col])}

只需使用您的样本输出再次测试,数字系数级别和50%阈值:

> rm(mtcars) # start fresh
> mtcars=head(mtcars) # first 6 rows for test
> for(col in cols){mtcars[,col]=factor(mtcars[,col])} # convert columns to factors

现在运行我的代码:

> for(col in cols){mtcars[,col]=thresh_factor(mtcars[,col],thresh=0.5)}
> head(mtcars[c("cyl","vs","am","gear","carb")])
                  cyl vs am gear carb
Mazda RX4           6  0  1    4  guz
Mazda RX4 Wag       6  0  1    4  guz
Datsun 710        guz  1  1    4    1
Hornet 4 Drive      6  1  0    3    1
Hornet Sportabout guz  0  0    3  guz
Valiant             6  1  0    3    1

看起来像您的预期输出。