2016-04-30 16 views
2

例のコードのように、行変数に一致する列名に基づいてデータフレームセルの値を置き換えたいとします。ネストされたループがこれを行うための好ましい方法ではないことを知るには十分知っていますが(よ​​り効率的なソリューションはおそらく非常に簡単です)、きれいなベクトル化アプローチを理解することはできませんでした。私はネストされた適用、すなわち適用によって呼び出される関数の内部での適用を迷惑にしているが、成功していないし、最善の方法でもないようである。列名と変数の一致に基づいてデータフレームのセル値を置き換えます

入力:

test.df 
    Group   G1  G2   G3 
1 G1 0.63910462 0.5738143 0.97428347 
2 G2 0.62578294 0.4653417 0.92010090 
3 G3 0.01136336 0.3163722 0.20266664 
4 G1 0.09054996 0.1984567 0.17488220 
5 G2 0.74865266 0.9862222 0.80725355 
6 G3 0.82855980 0.2668529 0.06786335 
7 G1 0.74310410 0.8861169 0.44801963 
8 G2 0.97329786 0.6682355 0.69658779 
9 G3 0.68696020 0.7362139 0.77452962 

出力:

test.df 
    Group   G1  G2  G3 
1 G1   NA 0.5738143 0.9742835 
2 G2 0.62578294  NA 0.9201009 
3 G3 0.01136336 0.3163722  NA 
4 G1   NA 0.1984567 0.1748822 
5 G2 0.74865266  NA 0.8072535 
6 G3 0.82855980 0.2668529  NA 
7 G1   NA 0.8861169 0.4480196 
8 G2 0.97329786  NA 0.6965878 
9 G3 0.68696020 0.7362139  NA 

コード:

test.df <- data.frame("Group"=rep(c("G1", "G2", "G3"), 3), "G1"=runif(9, 0, 1), "G2"=runif(9, 0, 1), "G3" = runif(9,0,1)) 

for (j in 1:ncol(test.df)) { 
    for(i in 1:nrow(test.df)) { 
    if(colnames(test.df)[j] == test.df$Group[i]) { 
     test.df[i,j] <- NA 
    } 
    } 
} 

私は、私はそれらを交換、交換する必要が値を取得するためにdplyrフィルタを使用できると思います、データフレームを再構成しますが、私は他のオプションの学習に興味があります。

+0

あなたのコードを正しく理解していることを確認するだけです。たとえば、行と列の名前が同じであるすべての値が削除されていますか? –

答えて

3

match()でベクトル化します。

idx <- cbind(seq_len(nrow(test.df)), match(test.df$Group, names(test.df)[-1])) 
test.df[-1][idx] <- NA 

idx我々はNAに変換したい値を収集するために使用するインデックス行列を作成します。最初の部分は、行数の長さだけのシーケンスです。 2番目の部分は、Group列と他の列の名前を一致させます。それから私たちは置き換えます。

これはtest.df

Group   G1  G2  G3 
1 G1   NA 0.5738143 0.9742835 
2 G2 0.62578294  NA 0.9201009 
3 G3 0.01136336 0.3163722  NA 
4 G1   NA 0.1984567 0.1748822 
5 G2 0.74865266  NA 0.8072535 
6 G3 0.82855980 0.2668529  NA 
7 G1   NA 0.8861169 0.4480196 
8 G2 0.97329786  NA 0.6965878 
9 G3 0.68696020 0.7362139  NA 

更新注になり:あなたにあなたがあなたの例を要因として、それを持っているので、最初のtest.df$Group <- as.character(test.df$Group)を使用する必要がありますので私は、test.dfの私の創造にstringsAsFactors = FALSEを持っていました。

+1

私は、 'test.df < - test.df [order(test.df $ Group)]]というグループを使って並べ替え、集めるために十分遠くにあり、次のレベルに進む方法を知らなかった。今、それは完全に意味をなさない。実際、私はそれを注文する必要はありませんでした。ワオ。 – Gopala

+0

非常に良い。ありがとう! – Nat

2
あなたが行と、サブ割り当てに分割でき

s = split(seq_len(nrow(test.df)), test.df$Group) 
for (k in names(s)) test.df[s[[k]], k] <- NA_real_ 

またはdata.tableと:あなたが実際にここdata.tableを使用する必要はありません

library(data.table) 
for (k in names(s)) set(test.df, i = s[[k]], j = k, v = NA_real_) 

注意を。私たちはsetをdata.frameに使用しています。この場合のsetの利点は、参照による変更です。

+0

これは偽の質問だと思われますが、ターゲットを見つけることができませんでした。 – Frank

0

バトンを渡す:

test.df %>% mutate(G1 = ifelse(Group == "G1", NA, G1)) 

# Group   G1  G2  G3 
# 1 G1   NA 0.3337749 0.3999944 
# 2 G2 0.25801678 0.4763512 0.3253522 
# 3 G3 0.47854525 0.8921983 0.7570871 
# 4 G1   NA 0.8643395 0.2026923 
# 5 G2 0.08424691 0.3899895 0.7111212 
# 6 G3 0.87532133 0.7773207 0.1216919 
# 7 G1   NA 0.9606180 0.2454885 
# 8 G2 0.83944035 0.4346595 0.1433044 
# 9 G3 0.34668349 0.7125147 0.2396294 

は今、どのように私はすべての列をスイープするのmutateを得るのですか?

関連する問題