2012-09-17 13 views
5

数字の値に再コードするのには、次のような巨大な1000 x 100000のデータフレームがあります。rのデータを記録する

myd <- data.frame (v1 = sample (c("AA", "AB", "BB", NA), 10, replace = T), 
        v2 = sample (c("CC", "CG", "GG", NA), 10, replace = T), 
        v3 = sample (c("AA", "AT", "TT", NA) , 10, replace = T), 
        v4 = sample (c("AA", "AT", "TT", NA) , 10, replace = T), 
        v5 = sample (c("CC", "CA", "AA", NA) , 10, replace = T) 
        ) 
myd 
    v1 v2 v3 v4 v5 
1 AB CC <NA> <NA> AA 
2 AB CG TT TT AA 
3 AA GG AT AT CA 
4 <NA> <NA> <NA> AT <NA> 
5 AA <NA> AA <NA> CA 
6 BB <NA> TT TT CC 
7 AA GG AA AT CA 
8 <NA> GG <NA> AT CA 
9 AA <NA> AT <NA> CC 
10 AA GG TT AA CC 

各変数には、潜在的に4つの一意の値があります。

unique(myd$v1) 

[1] AB AA <NA> BB 
Levels: AA AB BB 

unique(myd$v2) 

[1] CC CG GG <NA> 
    Levels: CC CG GG 

このようなユニークな値は、任意の組み合わせが可能ですが、2つのアルファベット( - NAを除く)で構成されています。たとえば、 "A"、 "B"は最初のケースでは "AA"、 "AB"、 "BB"の組み合わせになります。これらの数字コードはそれぞれ1、0、-1となります。同様に、第2のアルファベット「C」の場合、「G」は「CC」、「CG」、「GG」を作成するので、数字コードはそれぞれ1,0、-1となる。あなたのデータは、その下の数字のインデックスを持っている要因、であるという事実を利用することができます

myd 
     v1 v2 v3 v4  v5 
    1 0 1  <NA> <NA> 1 
    2 0 0  -1 -1  1 
    3 1 -1  0 0  0 
    4 <NA> <NA> <NA> 0  <NA> 
    5 1 <NA> 1 < NA>  0 
    6 -1 <NA> -1 -1  -1 
    7 1 -1 1  0  0 
    8 <NA> -1 <NA> 0  0 
    9 1 <NA> 0 <NA>  -1 
    10 1 -1 -1  1  -1 

答えて

7

:したがって上記MYDを再割り当てする必要があります。例えば

> as.numeric(myd$v1) 
[1] 2 2 1 NA 1 3 1 NA 1 1 

数値は因子のlevels()に対応する:

> levels(myd$v1) 
[1] "AA" "AB" "BB" 

だから1 == AA、2 == AB、3 == BB ...等々。

単純にデータを数値に変換し、必要な数学を適用してデータの縮尺を調整します。だから我々は2で引くことができ、その後、あなたの結果を得るために-1を掛け:

(sapply(myd, as.numeric) - 2) * -1 
#----- 
     v1 v2 v3 v4 v5 
[1,] 0 1 NA NA 1 
[2,] 0 0 -1 -1 1 
[3,] 1 -1 0 0 0 
[4,] NA NA NA 0 NA 
[5,] 1 NA 1 NA 0 
[6,] -1 NA -1 -1 -1 
[7,] 1 -1 1 0 0 
[8,] NA -1 NA 0 0 
[9,] 1 NA 0 NA -1 
[10,] 1 -1 -1 1 -1 
+1

'data.frame'の戻り値(lapply(myd、function(.x){})) ')または' .data.frame(lapply(myd、function (.x){ - (as.numeric(.x)-2)})) ' – mnel

8

は、私は別の解決策を掲載します - (超高速アプローチをdata.tableにスキップ!)

をしたい場合にAA, AB, BB1,0,-1などにコード化するには、索引付けを使用することができます。あなたが望むなら、これはあなたが別の記録を持つことができます!

自作recodeの機能

simple_recode <- function(.x, new_codes){ 
    new_codes[as.numeric(.x)] 
} 

as.data.frame(lapply(myd, simple_recode, new_codes = 1:-1)) 

使用factor

あなたは単に効率のためにlabels

as.data.frame(lapply(myd, factor, labels = 1:-1)) 

data.tableとして新しいレベルのfactorを呼び出すことにより、文字を再ラベル付けすることができます

あなたのデータが大きいなら、私はdata.tableのアプローチを提案します。これはメモリと時間効率になります。

library(data.table) 
DT <- as.data.table(myd) 
as.data.table(DT[,lapply(.SD, simple_recode, new_codes = 1:-1))]) 

as.data.table(DT[, lapply(.SD, setattr, 'levels', 1:-1)]) 

あるいは、より効率的にあるいは、もっと効率的にが(代わりにレベルを変更し、as.dataを回避することができます。テーブルコール)

for(name in names(DT)){ 
    setattr(DT[[name]],'levels',1:-1) 
    } 

setattrは参照していますのでコピーしません。この大きなデータセット

# some big data (100 columns, 1e6 rows) 
big <- replicate(100, factor(sample(c('AA','AB','BB', NA), 1e6, T)), simplify = F) 
bigDT <- as.data.table(big) 

system.time({ 
    for(name in names(big)){ 
    setattr(big[[name]],'levels',1:-1) 
    } 
    })) 

## user system elapsed 
## 0  0  0 
+0

良いもの。私はdata.tableの戦略が激しく速いと思う。 –

+0

'setattr'を使って' data.table'を 'inside'にすると効率的な' data.table'アプローチがあると確信しています。 – mnel

+0

'setattr'は内部に到達できます! - data.tableは素晴らしいです。 – mnel

4

に実証されているようにdata.tableとSETATTR

を使用して

実質的に瞬間的なアプローチLHSが適切な構造を有しているので、あなたは割り当てを設定する場合は、使用することができますあなたが望む値にインデックスとして暗黙的に係数の値を強制します:

> myd[] <- c(-1,0,1)[data.matrix(myd)] 
> myd 
    v1 v2 v3 v4 v5 
1 NA 0 0 0 1 
2 -1 1 0 0 -1 
3 0 NA 1 0 0 
4 NA -1 -1 0 -1 
5 -1 0 1 -1 NA 
6 0 NA 0 1 NA 
7 NA 0 1 NA -1 
8 0 0 0 -1 1 
9 -1 NA 1 -1 NA 
10 0 1 1 NA NA 

関連する問題