2016-08-17 7 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")) 

をIこれは最も早い(いくつかのアプローチでは1分以上ではなく、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) 

ポイントビーイングは、私はむしろ、ルックアップテーブルに一度それを行うだろういくつかのスクリプトの場所...私はより効率的に(9百万行のための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) 

を行うことができ、あなたが行われています。

9000万行の作業には、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で行う作業のために、より適していると言われているので、見て間違いなく価値があります。

+0

ありがとうございました@Karsten W. 問題は、提案されたソリューションがサンプルのデータフレームに関連しているかのように考えているようですが、そのように、 (CSVをインポートして作成された)既存のデータフレームとして私がそれらに対して行うことではなく、作成されています。 '変換'を使用するために 'as.character'と 'stringsAsFactors'をそれぞれのデータフレームの関連する列に適用しようとしましたが、 '文字'を強制するのに数秒かかり、一貫して '変換'がハングします。 –

+0

大規模データのための編集された答え。 –

+0

クール、ありがとう。私は少し遊びをして、どうやって行くのか見てみましょう。 –

関連する問題