5

数値に再コード化するために、次のような巨大な1000x100000のデータフレームがあります。

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は次のように再コーディングする必要があります。

 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
4

3 に答える 3

8

別の解決策を投稿します-(data.table超高速アプローチにスキップしてください!)

AA, AB, BB、などに再コーディングする場合1,0,-1は、インデックスを使用できます(数値解の係数とともに)。これにより、必要に応じて別の再コーディングが可能になります。

自作のリコード機能

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

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

使用するfactor

factor新しいレベルで次のように呼び出すことで、文字のラベルを簡単に変更できます。labels

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

data.table効率のために

データが大きい場合は、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.table呼び出しを回避します)

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

setattr参照によって変更されるため、コピーは行われません。

data.tableと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
于 2012-09-17T23:53:59.253 に答える
7

データが因子であり、その下に数値インデックスがあるという事実を利用できます。

例えば:

> 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
于 2012-09-17T16:06:01.657 に答える
4

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
于 2012-09-18T00:21:33.303 に答える