2011-12-21 114 views
0

我試圖用「forecast」中的預測值替換「test」中的NAs。我想用比賽,但我無法弄清楚。請記住ID和時間,創建一個由兩部分組成的唯一ID。有什麼建議麼? (記住我的數據集比這個例子大得多(行數= 32000))替換data.frame中的某些值R

test = data.frame(id =c(1,1,1,2,2,2), time=c(89,99,109,89,99,109), data=c(3,4,NA,5,2,NA)) 
forecast = data.frame(id =c(1,2), time=c(109,109), data=c(5,1)) 

所需的輸出

out = data.frame(id =c(1,1,1,2,2,2), time=c(89,99,109,89,99,109), data=c(3,4,5,5,2,1)) 
+0

是否與預測值被替換每NA值,或將一些殘留的NA在輸出? – joran 2011-12-21 19:11:52

回答

2

這裏是data.table溶液

test_dt <- data.table(test, key = c('id', 'time')) 
forecast_dt <- data.table(test, key = c('id', 'time')) 
forecast[test][,data := ifelse(is.na(data), data.1, data)] 

EDIT。基準測試:即使對於小型數據集,數據表也要快3倍。

庫(rbenchmark)

f_merge <- function(){ 
    out2 <- merge(test, forecast, by = c("id", "time"), all.x = TRUE) 
    out2 <- transform(out2, 
    newdata = ifelse(is.na(data.x), data.y, data.x), data.x = NULL, data.y = NULL) 
    return(out2) 
} 

f_dtable <- function(){ 
    test <- data.table(test, key = c('id', 'time')) 
    forecast <- data.table(forecast, key = c('id', 'time')) 
    test <- forecast[test][,data := ifelse(is.na(data), data.1, data)] 
    test$data.1 <- NULL 
    return(test) 
} 

benchmark(f_merge(), f_dtable(), order = 'relative', 
    columns = c('test', 'elapsed', 'relative')) 

     test elapsed relative 
2 f_dtable() 0.86  1.00 
1 f_merge() 2.26  2.63 
0

試試這個:

test$data[is.na(test$data)] <- forecast[((forecast$id %in% test$id) & (forecast$time %in% test$time)),]$data 
+0

對不起,這將無法正常工作。我最初並未指定我的數據集非常大......因此無法手動執行任何操作。 – mmann1123 2011-12-21 19:06:46

+0

我的代碼會給你與你想要的輸出(out)相同的結果。我認爲你必須編輯你的問題來提出一些建議你想要解決的問題是什麼 – jrara 2011-12-21 19:09:51

+0

它解決了* immediate *問題,但是對於其他選項不是很靈活或者靈活。這相當於'編輯(測試)'和手工更改東西......非常適合6行數據,對6000非常不利。 – Chase 2011-12-21 19:16:02

1

我會用merge來將數據加在一起,然後分兩步計算新列:

out2 <- merge(test, forecast, by = c("id", "time"), all.x = TRUE) 
> out2 
    id time data.x data.y 
1 1 89  3  NA 
2 1 99  4  NA 
3 1 109  NA  5 
4 2 89  5  NA 
5 2 99  2  NA 
6 2 109  NA  1 

#Compute new variable and clean up old ones: 

out2 <- transform(out2, newdata = ifelse(is.na(data.x), data.y, data.x), data.x = NULL, data.y = NULL) 
> out2 
    id time newdata 
1 1 89  3 
2 1 99  4 
3 1 109  5 
4 2 89  5 
5 2 99  2 
6 2 109  1 
+0

我上面評論的原因是,我打算建議簡單地用「NA」刪除行,然後「打開」預測值,但假定每個缺失值都被預測。 – joran 2011-12-21 19:31:08

+0

@Joran - 這將是偷偷摸摸和快速。我喜歡。 'merge'可能會有很多行變慢,所以我打算把相同的'data.table()'回答放在一起,但我敢打賭你提出的解決方案仍然是最快的。 – Chase 2011-12-21 19:44:43