问题描述:

I have a dataframe with 3 variables and 250K records. As an example consider

> 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

and want to swap values between V1 and V3 based on the value of V2 as follows:

if V2 == 'b' then V1 <- V3 and V3 <- V1

resulting in

V1 V2 V3

1 a 2

2 a 3

1 b 4

I tried a do loop but it takes forever. If I use Perl, it takes seconds. I believe this task can be done efficiently in R as well. Any suggestions are appreciated.

网友答案:

Try this

> 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
网友答案:

You can use transform to do this.

df <- transform(df, V3 = ifelse(V2 == 'b', V1, V3), V1 = ifelse(V2 == 'b', V3, V1))
网友答案:

Editted I got tripped up with column names, sorry. This works.

If you don't mind the rows ending up in different orders, this is kind of a 'cute' way to do this:

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)

Basically, that's just grabbing the rows where V2 == 'b', reverses the columns and slaps it back together with everything else. This can be extended if you have more columns that don't need switching; you'd just use an integer index with those values transposed, rather than just 3:1.

相关阅读:
Top