2016-08-17 94 views
0

總共R-newbie,在此處。請溫柔。使用R中的查找表查找/替換或映射

我有一個數據框中的數值表示種族(英國人口普查數據)。

# create example data 
id = c(1, 2, 3, 4, 5, 6, 7, 8, 9) 
ethnicode = c(0, 1, 2, 3, 4, 5, 6, 7, 8) 
df = data.frame(id, ethnicode) 

我可以做一個映射(或查找/替換)來創建一個列(或修改現有的列),其中包含人類可讀的值:

# map values one-to-one from numeric to string 
df$ethnicity <- mapvalues(df$ethnicode, 
          from = c(8, 7, 6, 5, 4, 3, 2, 1, 0), 
          to = c("Other", "Black", "Asian", "Mixed", 
            "WhiteOther", "WhiteIrish", "WhiteUK", 
            "WhiteTotal", "All")) 

所有的事情我試過這似乎是最快的(對於900萬行,大約20秒,而對於一些方法超過一分鐘)。

我似乎無法找到(或從我讀過的內容中理解)的東西是如何引用查找表。

# create lookup table 
ethnicode = c(8, 7, 6, 5, 4, 3, 2, 1, 0) 
ethnicity = c(("Other", "Black", "Asian", "Mixed", "WhiteOther", 
       "WhiteIrish", "WhiteUK", "WhiteTotal", "All") 
lookup = data.frame(ethnicode, ethnicity) 

問題的關鍵是,如果我想改變人類可讀的字符串,或做其他任何事情的過程中,我寧願做一次的查表,不是必須這樣做,在幾個放置在幾個腳本中......如果我能更有效地做到這一點(對於900萬行,在20秒以內)也是很好的做法。

我也想要很容易地確定「8」仍然等於「其他」(或任何等價物),並且「0」仍然等於「全部」等等,這在視覺上更加困難,上述方法。

在此先感謝。

回答

1

你可以使用這個命名向量。但是,您需要將族羣轉換爲字符。

df = data.frame(
    id = c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
    ethnicode = as.character(c(0, 1, 2, 3, 4, 5, 6, 7, 8)), 
    stringsAsFactors=FALSE 
) 

# create lookup table 
ethnicode = c(8, 7, 6, 5, 4, 3, 2, 1, 0) 
ethnicity = c("Other", "Black", "Asian", "Mixed", "WhiteOther", 
      "WhiteIrish", "WhiteUK", "WhiteTotal", "All") 
lookup = setNames(ethnicity, as.character(ethnicode)) 

然後,你可以做

df <- transform(df, ethnicity=lookup[ethnicode], stringsAsFactors=FALSE) 

和你做。

爲了處理900萬行,我建議你使用像sqlite或monetdb這樣的數據庫。 SQLite的,下面的代碼可能會有所幫助:

library(RSQLite) 

dbname <- "big_data_mapping.db" # db to create 
csvname <- "data/big_data_mapping.csv" # large dataset 

ethn_codes = data.frame(
    ethnicode= c(8, 7, 6, 5, 4, 3, 2, 1, 0), 
    ethnicity= c("Other", "Black", "Asian", "Mixed", "WhiteOther", "WhiteIrish", "WhiteUK", "WhiteTotal", "All") 
) 

# build db 
con <- dbConnect(SQLite(), dbname) 
dbWriteTable(con, name="main", value=csvname, overwrite=TRUE) 
dbWriteTable(con, name="ethn_codes", ethn_codes, overwrite=TRUE) 

# join the tables 
dat <- dbGetQuery(con, "SELECT main.id, ethn_codes.ethnicity FROM main JOIN ethn_codes ON main.ethnicode=ethn_codes.ethnicode") 

# finish 
dbDisconnect(con) 
#file.remove(dbname) 

monetdb被認爲是更適合你平時有R完成的任務,所以它是definitly值得一看。

+0

感謝這個,@Karsten W. 我遇到的問題是,建議的解決方案似乎考慮的問題,因爲儘管它涉及到例如dataframes,而正因爲如此,我可以爲他們」進行修改重新創建,而不是我將它們作爲預先存在的數據框(通過導入CSV創建)。 我試圖將「as.character」和「stringsAsFactors」應用於各自數據框中的相關列,以便使用「變換」,但是,強制執行「字符」需要幾秒鐘,而「變換」一直掛起。 –

+0

爲大數據方面編輯答案。 –

+0

很酷,謝謝。我會有一點戲劇,並看看我如何去。 –