2013-03-20 81 views
9

我使用因素有點不常見,並且通常會發現它們易於理解,但我經常對特定操作的細節很模糊。目前,我正在對「其他」進行編碼/摺疊的類別,但很少有觀察到這些類別,並且正在尋找一種快速方法來實現這一點 - 我可能有20個變量級別,但有興趣將其中一些變爲一個。R:因子水平,重新編碼休息到'其他'

data<-data.frame(employees=sample.int(1000,500), 
     naics=sample(c('621111','621112','621210','621310','621320','621330','621340','621391','621399','621410','621420','621491','621492','621493','621498','621511','621512','621610','621910','621991','621999'),100,replace=T) 

這裏是我的利率水平,以及它們在不同載體的標籤。

#levels and labels 
top8 <-c('621111','621210','621399','621610','621330','621310','621511','621420','621320') 
top8_desc <- c('Offices of physicians', 
      'Offices of dentists', 
      'Offices of all other miscellaneous health practitioners', 
      'Home health care services', 
      'Offices of Mental Health Practitioners', 
      'Offices of chiropractors', 
      'Medical Laboratories', 
      'Outpatient Mental Health and Substance Abuse Centers', 
      'Offices of optometrists') 

我可以使用factor()電話,枚舉所有這些,爲「其他」分類,每次類別有一些看法的。

假設上面的'top8'和'top8_desc'是實際的前8位,將數據$ naics聲明爲因子變量並將其他所有內容重新編碼爲'other'的最佳方式是什麼?

回答

6

我認爲最簡單的方法是將所有不在前8位的naics重新標記爲特殊值。

data$naics[!(data$naics %in% top8)] = -99 

然後你就可以把它變成一個因素

factor(data$naics, exclude=-99) 
+1

嗯,涉及實際投擲數據遠,而不是改變分類,但這可能是編碼作爲一個因素無論如何首先。我想這並不重要。 – ako 2013-03-20 22:24:09

+1

您可以隨時使用轉換後的代碼在數據框中創建額外的列。 – kith 2013-03-20 23:25:02

+1

我試過你的回答的這種變化:'水平(數據$ naics)[其中(!水平(數據$ naics)%in%top8)] < - 「其他」' – ako 2013-03-20 23:47:46

0

我已經writen一個函數來做到這一點,可能是有用的給別人可能時使用「排除」選項? 我首先檢查一個相對的方式,如果一個級別發生少於mp百分之基數。之後,我會檢查以將最高級別數限制爲ml。

ds是data.frame類型的數據集,我對cat_var_names中出現的所有列作爲因子執行此操作。

cat_var_names <- names(clean_base[sapply(clean_base, is.factor)]) 

recodeLevels <- function (ds = clean_base, var_list = cat_var_names, mp = 0.01, ml = 25) { 
    # remove less frequent levels in factor 
    # 
    n <- nrow(ds) 
    # keep levels with more then mp percent of cases 
    for (i in var_list){ 
    keep <- levels(ds[[i]])[table(ds[[i]]) > mp * n] 
    levels(ds[[i]])[which(!levels(ds[[i]])%in%keep)] <- "other" 
    } 

    # keep top ml levels 
    for (i in var_list){ 
    keep <- names(sort(table(ds[i]),decreasing=TRUE)[1:ml]) 
    levels(ds[[i]])[which(!levels(ds[[i]])%in%keep)] <- "other" 
    } 
    return(ds) 
} 
+0

這並不能回答這個問題。要批評或要求作者澄清,在他們的帖子下留下評論 - 你總是可以評論你自己的帖子,一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation),你會能夠[評論任何帖子](http://stackoverflow.com/help/privileges/comment)。 – Sliq 2013-08-20 14:17:25

3

遲進入

這裏是plyr::mapvalues的包裝,它允許一個remaining參數(您other

library(plyr) 

Mapvalues <- function(x, from, to, warn_missing= TRUE, remaining = NULL){ 
    if(!is.null(remaining)){ 
    therest <- setdiff(x, from) 
    from <- c(from, therest) 
    to <- c(to, rep_len(remaining, length(therest))) 
    } 
    mapvalues(x, from, to, warn_missing) 
} 
# replace the remaining values with "other" 
Mapvalues(data$naics, top8, top8_desc,remaining = 'other') 
# leave the remaining values alone 
Mapvalues(data$naics, top8, top8_desc)