在R中对数据进行分类

时间:2014-07-05 04:31:40

标签: r

我试图根据数据类型将我的数据分类到不同的组中。我的数据和代码如下:

bank    ROE
bank1   0.73
bank2   0.94
bank3   0.62
bank4   0.57
bank5   0.31
bank6   0.53
bank7   0.39
bank8   0.01
bank9   0.16
bank10  0.51
bank11  0.84
bank12  0.18

sob <- c('bank1', 'bank2','bank3',)
fob <- c('bank4','bank5', 'bank6')
jov <- c('bank7', 'bank8','bank9', 'bank10','bank11')

test$type <- ifelse(test$bank == sob, 1, ifelse(test$bank == fob, 2, ifelse(test$bank == jov, 3,     4)))
test

然而,由于类别出现错误,此代码无效,我收到此警告:

Warning messages:
1: In is.na(e1) | is.na(e2) :
longer object length is not a multiple of shorter object length
2: In `==.default`(test1$bank, jov) :
longer object length is not a multiple of shorter object length

任何人都可以告诉我我做错了什么以及我应该做些什么才能做到正确?

由于

3 个答案:

答案 0 :(得分:2)

你应该使用%in% - 运算符而不是身份 - 你在这里与向量进行比较。

像这样:

test$type <- ifelse(test$bank %in% sob, 1, ifelse(test$bank %in% fob, 2, ifelse(test$bank %in% jov, 3,     4)))

> test
     bank  ROE type
1   bank1 0.73    1
2   bank2 0.94    1
3   bank3 0.62    1
4   bank4 0.57    2
5   bank5 0.31    2
6   bank6 0.53    2
7   bank7 0.39    3
8   bank8 0.01    3
9   bank9 0.16    3
10 bank10 0.51    3
11 bank11 0.84    3
12 bank12 0.18    4

或者,为了避免繁琐的if-else结构,你可以做一个因子的分类重置级别。

首先复制银行变量 测试$的类型&lt; -test $银行

然后,使用上面定义的向量(呜咽,表情,工作)重新设置等级。请注意最后一步,'other'设置为剩余值,因为bank12未在其他向量中定义。

levels(test$type) <- list('sob' = sob,
                          'fob' = fob,
                          'jov' = jov,
                          'other' = 'bank12')

导致

> test
     bank  ROE  type
1   bank1 0.73   sob
2   bank2 0.94   sob
3   bank3 0.62   sob
4   bank4 0.57   fob
5   bank5 0.31   fob
6   bank6 0.53   fob
7   bank7 0.39   jov
8   bank8 0.01   jov
9   bank9 0.16   jov
10 bank10 0.51   jov
11 bank11 0.84   jov
12 bank12 0.18 other

答案 1 :(得分:2)

代码中的==运算符会将向量test$bank与向量jov进行比较。由于这些向量具有不同的长度(12和5),并且较长的向量不是较短的向量的倍数,例如在sob(长度为3)的情况下,您会收到警告消息。

要评估某个值是否等于向量中的任何值,您可以使用%in%运算符,就像@ako建议的那样。但是,使用群组factorlevels时,这些功能非常有用。将变量指定为因子,然后设置新的级别。

test <- data.frame(
  bank = c('bank1','bank2','bank3','bank4','bank5','bank6','bank7','bank8','bank9','bank10','bank11','bank12'),
  ROE = c(0.73,0.94,0.62,0.57,0.31,0.53,0.39,0.01,0.16,0.51,0.84,0.18)
)

test$bank <- factor(test$bank)

levels(test$bank) <- list(
  '1' = c('bank1', 'bank2','bank3'),
  '2' = c('bank4','bank5', 'bank6'),
  '3' = c('bank7', 'bank8','bank9', 'bank10','bank11'),
  'other' = NA
)

test$bank[is.na(test$bank)] <- 'other'

答案 2 :(得分:1)

您也可以尝试:

lst1 <- list(sob, fob, jov)
test$type <- setNames(rep(seq_along(lst1),sapply(lst1,length)),unlist(lst1))[test$bank]
test$type[is.na(test$type) ] <- 4

test$type
#[1] 1 1 1 2 2 2 3 3 3 3 3 4