2016-11-26 2 views
2

Используя этот data.frame:IfElse: объединить 3 категории в одну

df <- read.table(text = c(" 
ID cat1 cat2 cat3 
site1 High High High 
site1 High High Medium 
site1 High High Low 
site1 High Medium High 
site1 High Medium Medium 
site1 High Medium Low 
site1 High Low High 
site1 High Low Medium 
site1 High Low Low 
site1 Medium High High 
site1 Medium High Medium 
site1 Medium High Low 
site1 Medium Medium High 
site1 Medium Medium Medium 
site1 Medium Medium Low 
site1 Medium Low High 
site1 Medium Low Medium 
site1 Medium Low Low 
site1 Low High High 
site1 Low High Medium 
site1 Low High Low 
site1 Low Medium High 
site1 Low Medium Medium 
site1 Low Medium Low 
site1 Low Low High 
site1 Low Low Medium 
site1 Low Low Low 
"), header =T) 

Я хочу, чтобы создать новый столбец new_category на основе cat1, cat2 и cat3.

Я хочу, чтобы каждый ряд в new_category имел общий класс «или слово» в cat1, cat2 и cat3. Если все значения различны (Высокий, Средний и Низкий), new_category возьмет самый высокий класс (High в этом случае).

Например

Если cat1 = High, cat2 = High, cat3= Medium, то new_category = High

Если cat1 = High, cat2 = Medium, cat3= Low, то new_category = High

Если cat1 = Medium, cat2 = Medium, cat3= Low, то new_category = Medium

Я могу это сделать, используя ifelse. Тем не менее, существует множество комбинаций cat1 и cat2 и cat3.

Любое предложение для более быстрого или простого способа сделать это?

ответ

5

для рядов с повторяющимися уровнями, выберите наиболее часто используемый, если есть такой уровень; иначе выберите тот, который имеет самый низкий ранг;

# convert each row to ordered vector and find the entry with min rank; 
df$new_category <- apply(
    df[2:4], 1, function(x){ 
     f <- table(x) 
     if(max(f) > 1){ 
      names(f)[which.max(f)] 
     }else{ 
      y <- factor(x, levels = c('High', 'Medium', 'Low'), ordered = T) 
      as.character(min(y)) 
     } 
    } 
) 
# > df 
#  ID cat1 cat2 cat3 new_category 
# 1 site1 High High High   High 
# 2 site1 High High Medium   High 
# 3 site1 High High Low   High 
# 4 site1 High Medium High   High 
# 5 site1 High Medium Medium  Medium 
# 6 site1 High Medium Low   High 
# 7 site1 High Low High   High 
# 8 site1 High Low Medium   High 
# 9 site1 High Low Low   Low 
# 10 site1 Medium High High   High 
# 11 site1 Medium High Medium  Medium 
# 12 site1 Medium High Low   High 
# 13 site1 Medium Medium High  Medium 
# 14 site1 Medium Medium Medium  Medium 
# 15 site1 Medium Medium Low  Medium 
# 16 site1 Medium Low High   High 
# 17 site1 Medium Low Medium  Medium 
# 18 site1 Medium Low Low   Low 
# 19 site1 Low High High   High 
# 20 site1 Low High Medium   High 
# 21 site1 Low High Low   Low 
# 22 site1 Low Medium High   High 
# 23 site1 Low Medium Medium  Medium 
# 24 site1 Low Medium Low   Low 
# 25 site1 Low Low High   Low 
# 26 site1 Low Low Medium   Low 
# 27 site1 Low Low Low   Low 
+0

Perfect :-) Большое спасибо за ваше время и помощь. – aelwan

+1

добро пожаловать. Я также узнал, что 'min' и' max' не могут применяться к обычным факторам, но могут применяться к упорядоченным факторам. :) – mt1022

+4

Я добавляю его здесь, так как его точно такая же идея - разные функции. Чтобы избежать табуляции и 'which.max' по строке, альтернативой является табуляция спереди и использование' max.col'. И используйте 'ifelse', так как мы теперь работаем над длиной> 1 вектором. То есть 'tab = table (строка (df [-1]), as.matrix (df [-1])); ifelse (rowSums (tab! = 0) == 3, «High», colnames (tab) [max.col (вкладка, «first»)]) ' –

Смежные вопросы