#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
toother
. Тогда любые неопределенные уровни будут в равной степени равны 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