Ifelse:将3个类别合并为一个

时间:2016-11-26 08:39:35

标签: r if-statement

使用此data.frame:

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_categorycat1cat2创建一个名为cat3的新列。

我希望new_category中的每一行都有cat1cat2cat3中的公共类“或字”。如果所有值都不同(高,中和低),则new_category将采用最高级别(在这种情况下为High)。

例如

  

如果cat1 = Highcat2 = Highcat3= Medium,则new_category = High

     

如果cat1 = Highcat2 = Mediumcat3= Low,则new_category = High

     

如果cat1 = Mediumcat2 = Mediumcat3= Low,则new_category = Medium

我可以使用ifelse执行此操作。但是,cat1cat2以及cat3的组合很多。

有什么建议可以更快或更轻松地做到这一点吗?

1 个答案:

答案 0 :(得分: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