我有一个包含3个变量和250K记录的数据帧。举个例子来考虑
> 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之间的值,如下所示:
如果V2 == 'b'
则V1 <- V3
和V3 <- V1
导致
V1 V2 V3
1 a 2
2 a 3
1 b 4
我尝试了一个do循环但它需要永远。如果我使用Perl,则需要几秒钟。我相信这项任务也可以在R中有效地完成。任何建议都表示赞赏。
答案 0 :(得分:17)
试试这个
> 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
答案 1 :(得分:11)
您可以使用transform
执行此操作。
df <- transform(df, V3 = ifelse(V2 == 'b', V1, V3), V1 = ifelse(V2 == 'b', V3, V1))
答案 2 :(得分: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
。