在R中的行中交换值

时间:2015-12-04 13:29:49

标签: r

当左值大于正确值时,我想在每一行中交换V2和V3值?因此,较大的值应该在V3中,而较小的值应该在V2中。

V1    V2           V3 
3     113634042   112634042    
15    42130650    43130646    
5     59947488    60947483    
47    65968160    66968149    
16    30674811    29674823    
5     10441822    9441835

4 个答案:

答案 0 :(得分:5)

我们可以使用pminpmax来执行该任务。它们将返回行数长度的向量,一个具有第二列和第三列之间的最小值,一个具有最大值。然后我们用新值替换原来的2列:

df[,2:3]<-cbind(pmin(df[,2],df[,3]),pmax(df[,2],df[,3]))

df
#   V1        V2        V3
# 1  3 112634042 113634042
# 2 15  42130650  43130646
# 3  5  59947488  60947483
# 4 47  65968160  66968149
# 5 16  29674823  30674811
# 6  5   9441835  10441822

数据:

df <- structure(list(V1 = c(3L, 15L, 5L, 47L, 16L, 5L), V2 = c(113634042L, 
42130650L, 59947488L, 65968160L, 30674811L, 10441822L), V3 = c(112634042L, 
43130646L, 60947483L, 66968149L, 29674823L, 9441835L)), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -6L))

另一种选择是使用applysort

t(apply(df[,2:3],1,sort))
#           [,1]      [,2]
# [1,] 112634042 113634042
# [2,]  42130650  43130646
# [3,]  59947488  60947483
# [4,]  65968160  66968149
# [5,]  29674823  30674811
# [6,]   9441835  10441822

apply版本似乎比pminpmax慢:

Unit: microseconds
  expr     min      lq      mean   median       uq      max neval cld
  pmax  54.202  57.089  68.17331  68.4750  72.0025  167.738   100  a 
 apply 561.263 581.950 624.66715 598.4675 630.5395 1179.936   100   b

答案 1 :(得分:4)

使用transform以及pminpmax

transform(DF, V2 = pmin(V2, V3), V3 = pmax(V2, V3))

,并提供:

  V1        V2        V3
1  3 112634042 113634042
2 15  42130650  43130646
3  5  59947488  60947483
4 47  65968160  66968149
5 16  29674823  30674811
6  5   9441835  10441822

注意:以下是可重现的数据:

Lines <- "3     113634042   112634042    
15    42130650    43130646    
5     59947488    60947483    
47    65968160    66968149    
16    30674811    29674823    
5     10441822    9441835"


DF <- read.table(text = Lines)

答案 2 :(得分:0)

这是一个data.table解决方案,按引用编辑列(复制的etienne数据集):

library(data.table)


df <- structure(list(V1 = c(3L, 15L, 5L, 47L, 16L, 5L), V2 = c(113634042L, 
42130650L, 59947488L, 65968160L, 30674811L, 10441822L), V3 = c(112634042L, 
43130646L, 60947483L, 66968149L, 29674823L, 9441835L)), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -6L))

dtable <- data.table(df)

dtable[,c('V2','V3') := .(ifelse(V2 > V3, V3, V2), ifelse(V2 > V3, V2, V3))]

答案 3 :(得分:0)

您只需使用错误的顺序替换行,并使用相同的重新排列行:

df[df$V2>df$V3,2:3] = df[df$V2>df$V3,3:2]