2011-10-12 9 views
11

3つの変数と250Kのレコードを持つデータフレームがあります。一例として2列間で値を入れ替える方法

> df <- data.frame(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1)) 
V1 V2 V3 
1 a 2 
2 a 3 
4 b 1 

を考慮し、以下のようにV2の値に基づいて、V1とV3との間の値を交換したい:私は試した V1 <- V3次いでV2 == 'b'場合

V1 V2 V3 
1 a 2 
2 a 3 
1 b 4 

もたらすV3 <- V1 ループは永遠にかかる。 Perlを使用すると、数秒かかる。私はこの仕事がRでも効率的に行えると信じています。どんな提案も感謝しています。

+0

私が尋ねることに気をつけなければ、この状況がどのようになったのか不思議です。私は調査データを扱うように設計されたソフトウェアを使った経験がありますが、ITデータベースとの統合の流れに沿ってデータ構造の問題が浮き彫りになってきています。我々はテーブルにものを格納する。だから私はあなたの状況がどうなったのか不思議です:) – Jonathan

答えて

4

編集済み私は列名でトリップしました。これは機能します。

あなたは異なる順序で終わる行を気にしない場合は、これはこれを行うには「かわいい」道のようなものです:

dat <- read.table(textConnection("V1 V2 V3 
1 a 2 
2 a 3 
4 b 1"),sep = "",header = TRUE) 

tmp <- dat[dat$V2 == 'b',3:1] 
colnames(tmp) <- colnames(dat) 
rbind(dat[dat$V2 != 'b',],tmp) 

基本的に、それはちょうどV2 == 'b'は、反転した行をつかみましたそれを他のものと一緒に戻します。これは、切り替えが必要ない列がさらに多い場合に拡張できます。単に3:1ではなく、転置された値を持つ整数インデックスを使用します。

+0

これは素晴らしい方法です! +1 – Chris

14

は、あなたがこれを行うにはtransformを使用することができ、この

> df <- data.frame(V1=c(1,2,4), V2=c("a","a","b"), V3=c(2,3,1)) 
> df[df$V2 == "b", c("V1", "V3")] <- df[df$V2 == "b", c("V3", "V1")] 
> df 
    V1 V2 V3 
1 1 a 2 
2 2 a 3 
3 1 b 4 
+0

すっきりしたソリューション! +1。 – TMS

10

を試してみてください。

df <- transform(df, V3 = ifelse(V2 == 'b', V1, V3), V1 = ifelse(V2 == 'b', V3, V1)) 
+0

私は試しています x = read.table( "1.txt") x < - transform(x、x [[1]] < - ifelse(x [[1]]> x [[2]]、x x [[1]]、x [2]]、x [[2]]、x [[2] ])) しかし成功しません! – phoenix

関連する問題