Home > Back-end >  How to switch elements in data.frame according to size?
How to switch elements in data.frame according to size?

Time:02-10

I am looking for an R function that allows swapping two elements in a data frame under a certain constraint.

For example:

If I have a dataframe (5rows, 5cols) and I want that all elements in column 2 that are greater than the corresponding elements in column 3 to be swapped. As a result, all the elements of column 2 greater than those of column 3 would move to column 3 and vice-versa.

Your help is much appreciated.

CodePudding user response:

Reproducible sample data:

set.seed(42)
dat <- as.data.frame(matrix(sample(10, size=25, replace=TRUE), nrow=5))
dat
#   V1 V2 V3 V4 V5
# 1  1  4  7 10  4
# 2  5  2  4  2  5
# 3  1 10  9  3  5
# 4  9  1  5  9  4
# 5 10  8  4  9  2

Working solution:

dat[c("V1", "V2")] <- lapply(list(pmin, pmax), function(fun) do.call(fun, dat[c("V1", "V2")]))
dat
#   V1 V2 V3 V4 V5
# 1  1  4  7 10  4
# 2  2  5  4  2  5
# 3  1 10  9  3  5
# 4  1  9  5  9  4
# 5  8 10  4  9  2

CodePudding user response:

You can use

set.seed(123)
x = as.data.frame(matrix(sample(1:25), nrow = 5))
#   V1 V2 V3 V4 V5
# 1 15 18  9 25  2
# 2 19 11 21 17 16
# 3 14  5 24  1  7
# 4  3 23 20 12  8
# 5 10  6 22 13  4

x[, 2:3] = t(apply(x[, 2:3], 1, sort))
#   V1 V2 V3 V4 V5
# 1 15  9 18 25  2
# 2 19 11 21 17 16
# 3 14  5 24  1  7
# 4  3 20 23 12  8
# 5 10  6 22 13  4

CodePudding user response:

You can use swap from seqinr :

x = as.data.frame(matrix(sample(1:25), nrow = 5))
x
#>   V1 V2 V3 V4 V5
#> 1  1  7 22  6 10
#> 2  9 17 16 13  2
#> 3 23 19 12 24 20
#> 4  3 14 15  5 25
#> 5 18  8 11 21  4
ind <- (x[2] > x[3])
seqinr::swap(x[ind, 2], x[ind, 3])
x
#>   V1 V2 V3 V4 V5
#> 1  1  7 22  6 10
#> 2  9 16 17 13  2
#> 3 23 12 19 24 20
#> 4  3 14 15  5 25
#> 5 18  8 11 21  4
  • Related