категоризация данных в R

#r

#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
  

Кто-нибудь может показать мне, что я сделал не так и что я должен сделать, чтобы все было правильно?

Спасибо

Комментарии:

1. Для начала вам следует разобраться в разнице между == и %in% .

Ответ №1:

Вы должны использовать %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, вы могли бы выполнить классификацию, сбрасывающую уровни фактора.

сначала скопируйте переменную банка test$type<-test$bank

затем повторно установите уровни, используя векторы, определенные выше (sob, fob, job). Обратите внимание, что для последнего шага '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. Привет, спасибо всем вам за предложение, я настроил оператор == на %в%, и это сработало отлично. Что касается предложения использовать factor, мне просто интересно, было ли у меня намного больше банка, чем в этом примере, как я могу установить ‘other’ для остальных данных? Я новичок в R, поэтому, пожалуйста, извините за мой вопрос, если он слишком тривиален для вас, ребята. Спасибо

2. Вы можете установить уровень «другое», чтобы NA затем присвоить всем с NA уровнем «другое». test$type[is.na(test$type)] <- 'other'

3. Это должно быть то же самое, что просто пропустить четвертую строку в списке, установив levels(test$type)=list('sob' = sob, 'fob' = fob,'jov' = jov) ; без явного присвоения NA to other . Тогда любые неопределенные уровни будут в равной степени равны NA. Затем @sbebobs тестирует$type[is.na (test$type)] <- ‘other’ может использоваться для них.

4. Спасибо bebop, например, за полезное предложение.

5. Спасибо ako. Я сделаю это

Ответ №2:

== Оператор в вашем коде сравнивает вектор test$bank с векторами jov . Поскольку эти векторы имеют разную длину (12 и 5), а более длинный вектор не кратен более короткому, как в случае sob (длины 3), вы получаете предупреждающее сообщение.

Чтобы оценить, равно ли значение любому из значений в векторе, вы можете использовать %in% оператор, как предлагает @ako. Однако при работе с группами factor и levels являются полезными функциями. Укажите переменную в качестве фактора, затем задайте новые уровни.

 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'
  

Комментарии:

1. 1. Это то, что я сделал в своей Factor оболочке для factor .

Ответ №3:

Вы также могли бы попробовать:

 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