寻找一种更简洁的方法来重新分类变量

时间:2014-04-22 10:24:07

标签: r dplyr

我有一个整数年龄的向量,我想把它变成多个类别:

ages <- round(runif(10, 0, 99))

现在我希望将此变量分为三类,具体取决于年龄。我希望输出对象ages.cat看起来像这样:

   young mid old
1      0   0   1
2      1   0   0
3      1   0   0
4      1   0   0
5      1   0   0
6      0   1   0
7      1   0   0
8      0   0   1
9      0   1   0
10     0   1   0

目前我正在使用以下代码创建此对象:

ages.cat <- array(0, dim=c(10,3)) # create categorical object for 3 bins
ages.cat[ages < 30, 1] <- 1
ages.cat[ages >= 30 & ages < 60, 2] <- 1
ages.cat[ages >= 60, 3] <- 1

ages.cat <- data.frame(ages.cat)
names(ages.cat) <- c("young", "mid", "old")

必须有一种更快捷,更简洁的方式来重新编码这些数据 - 玩dplyr 但是无法通过其功能看到这个特定问题的解决方案。有任何想法吗?什么是&#39;规范&#39;在基础R或使用包解决这个问题?无论选择哪种方式,我都确定他们会比我笨重的代码更简洁!

2 个答案:

答案 0 :(得分:3)

它的两个单行。

使用cut创建一个因素:

ages <- round(runif(10, 0, 99))
ageF=cut(ages,c(-Inf,30,60,Inf),labels=c("young","mid","old"))
> ageF
 [1] young mid   young young old   mid   old   young old   old  
Levels: young mid old

通常,您将其作为一个因素并使用它,如果您正在使用R的建模功能,他们将为您计算矩阵。但如果你自己这样做:

使用model.matrix创建矩阵,使用-1删除截距并为每个级别创建列:

> m = model.matrix(~ageF-1)
> m
   ageFyoung ageFmid ageFold
1          1       0       0
2          0       1       0
3          1       0       0
4          1       0       0
5          0       0       1
6          0       1       0
7          0       0       1
8          1       0       0
9          0       0       1
10         0       0       1
attr(,"assign")
[1] 1 1 1
attr(,"contrasts")
attr(,"contrasts")$ageF
[1] "contr.treatment"

你可以忽略所有对比的东西,它只是一个矩阵,有一些额外的建模属性。

答案 1 :(得分:1)

试试这个:

library(dplyr)

ages <- 
  data.frame(ages = round(runif(10, 0, 99))) %.%
  mutate(id = 1:n(), 
         cat = factor(ifelse(ages < 30, "young",
                             ifelse(ages >= 30 & ages < 60, 
                                    "mid", "old")))) %.%
  dcast(id ~ cat, value.var = 'ages', length)