2017-03-21 4 views
0

カテゴリカルのすべての値をランク別に変更したい。ランクは、列内のソートされた固有の要素のインデックスを使用して決定できます。例えば値をRategyicalからnominalに変更する

> data[1:5,1] 
[1] "B2" "C4" "C5" "C1" "B5" 

その後、私は列内のこれらのエントリは、カテゴリ値

> data[1:5,1] 
[1] "1" "4" "5" "3" "2" 

別の列に置き換えたい:

> data[1:5,3] 
[1] "Verified"  "Source Verified" "Not Verified" "Source Verified" "Source Verified" 

その後更新された列:

> data[1:5,3] 
[1] "3" "2" "1" "2" "2" 

この作業にこのコードを使用しましたが、時間がかかります。

for(i in 1:ncol(data)){ 
    if(is.character(data[,i])){ 
    temp <- sort(unique(data[,i])) 
    for(j in 1:nrow(data)){ 
     for(k in 1:length(temp)){ 
     if(data[j,i] == temp[k]){ 
      data[j,i] <- k} 
     } 
    } 
    } 
} 

可能であれば、効率的な方法を提案してください。おかげさまで

+0

を '' plyr's mapvalues'を見てみましょう。 – count

答えて

1

ここでは、base Rの解決法を示します。ヘルパー関数を作成して、各列を独自のソートされた値をレベルとして使用して係数に変換します。これは、as.integerを使用してランキングの値を取得する以外は、あなたが行ったことに似ています。

rank_fac <- function(col1) 
    as.integer(factor(col1,levels = unique(col1))) 

一部のデータの例:

dx <- data.frame(
    col1= c("B2" ,"C4" ,"C5", "C1", "B5"), 
    col2=c("Verified" , "Source Verified", "Not Verified" , "Source Verified", "Source Verified") 
) 

は、forループを使用せずにそれを適用します。副作用を避けるためにここでlapplyを使用する方がよいでしょう。

data.frame(lapply(dx,rank_fac) 

結果:

#  col1 col2 
# [1,] 1 3 
# [2,] 4 2 
# [3,] 5 1 
# [4,] 3 2 
# [5,] 2 2 

data.table構文糖を使用して

library(data.table) 
setDT(dx)[,lapply(.SD,rank_fac)] 
# col1 col2 
# 1: 1 3 
# 2: 4 2 
# 3: 5 1 
# 4: 3 2 
# 5: 2 2 

簡単なソリューション:

のみas.integerを使用する:

setDT(dx)[,lapply(.SD,as.integer)] 
0を
+1

丁寧ですが、 'data.frame(lapply(dx、rank_fac)'や 'replace(dx、、lapply(dx、rank_fac))'や 'sapply(dx、rank_fac)'も 'do.call (cbind..' – thelatemail

0

matchを使用する:

# df is your data.frame  
df[] <- lapply(df, function(x) match(x, sort(unique(x)))) 
関連する問題