Home > OS >  Sorting Nested Lists in R with Python Semantics
Sorting Nested Lists in R with Python Semantics

Time:12-10

I need to replicate the following sorting behavior (found in Python) in R.

Assuming In Python:

l = [(0,0), (1,-1), (-1,0), (-1,-1)]

>>> sorted(l)
[(-1, -1), (-1, 0), (0, 0), (1, -1)]

>>> min(l)
[(-1, -1)]

The equivalent data structure in R is:

l <- list(c(0,0), c(1,-1), c(-1,0), c(-1,-1))

The sort() and sort.list() methods are not implemented for non-atomic vectors.

In my use-case I can guarantee a list of length 2 vectors, so this works:

sorted <- function(list){
  m=matrix(unlist(list), ncol = 2, byrow = T)
  asplit(
    m[order(m[,1],m[,2]),],
    1
  )
}

Replicating the behavior of min from Python is easy, just relies on the correct function of a sorted implementation in R.

min.list <- function(list) sorted(list)[1]

Advice on implementing the same behavior as sorted is greatly appreciated, and considerations for efficiency are especially welcomed.

Unnecessary for my implementation, but an additional consideration is the sorted behavior when the sub-lists varies in length.

>>> sorted([(0,0), (1,1), (0,-1), (0,-1, 0), (0,-1,-1), (0, 0, 0)])

[(0, -1), (0, -1, -1), (0, -1, 0), (0, 0), (0, 0, 0), (1, 1)]

Thanks in advance

CodePudding user response:

Maybe we can try this way

> l <- list(c(0, 0), c(1, 1), c(0, -1), c(0, -1, 0), c(0, -1, -1), c(0, 0, 0))

> l[order(sapply(l, toString))]
[[1]]
[1]  0 -1

[[2]]
[1]  0 -1 -1

[[3]]
[1]  0 -1  0

[[4]]
[1] 0 0

[[5]]
[1] 0 0 0

[[6]]
[1] 1 1

CodePudding user response:

One option is to row bind to a matrix, split by column and use order() to get the indices. For ragged data, it's necessary to standardize the lengths first but obviously this step can be skipped for slightly increased efficiency if the data is guaranteed to be of equal length.

l <- list(c(0, 0), c(1, 1), c(0, -1), c(0, -1, 0), c(0, -1, -1), c(0, 0, 0))

l[do.call(order, c(asplit(do.call(rbind, lapply(l,
    `length<-`, max(lengths(l)))), 2), na.last = FALSE))]

[[1]]
[1]  0 -1

[[2]]
[1]  0 -1 -1

[[3]]
[1]  0 -1  0

[[4]]
[1] 0 0

[[5]]
[1] 0 0 0

[[6]]
[1] 1 1
  • Related