2012-06-15 107 views
1

讓說我有R.以下數據通過的另一個因素就近水平替換因素的水平

training = factor(c(1,1,3,2,1,3,2,34,67,34)) 
test = factor(c(1,1,2,30,65,30)) 

(我的數據要複雜得多,這是一個簡化)

我想檢查測試集中的水平是否存在於訓練集中,如果不是,則用訓練集中最接近的值替換。 例如,測試集中的級別30和65不存在於訓練集中,所以我想分別用34和67代替它們。

目前,我創建了以下代碼。

replacefactor <- function(dat,new_factor,near_factor) { 
if (!(near_factor %in% levels(dat))){ 
    levels(dat) <- c(levels(dat),near_factor) 
} 
dat[dat==new_factor] <- near_factor 
dat <- factor(dat) 
} 

test <- replacefactor(test,30,34) 
test <- replacefactor(test,65,67) 

它的工作,但我需要手動指定水平。由於我的數據量很大,這對我來說不實用。

我不知道如何在訓練集中找到最接近的值。 我可以使用for循環來自動化它。

回答

4

首先要獲取不匹配的水平:

test.missing <- levels(test)[!levels(test) %in% levels(training)] 

然後編寫一個函數來沿着他們跑,找到最接近的匹配:

myfun <- function(x, y) { 
    levels(y)[which.min(abs(as.integer(levels(y)) - as.integer(x)))] 
} 

> unlist(lapply(test.missing, myfun, training)) 
[1] "34" "67" 

那麼這可以被分配到正確的級別:

levels(test)[!levels(test) %in% levels(training)] <- unlist(lapply(test.missing, myfun, training)) 

> levels(test) 
[1] "1" "2" "34" "67" 
+0

不應該'myfun'的主體有'as.integer(levels(x))',而不是'as.integer(x)'? (我會在你回覆後刪除它)。 –

+0

謝謝!有用。你讓我很快樂。 –

+0

@ JoshO'Brien它不應該,因爲我的變量'test.missing'已經是作爲一個字符因子的水平。你可以寫不同的函數,並檢查函數中是否存在缺失,然後根據你的建議更改代碼,如果它實際上缺失。 – Justin