0

I know this is a common question, but the common answer of r[order(unlist(r))] isn't working due to numerical keys. I can't find any answers after a while of searching. I did see How can I get top n values with its index in R? but that uses a dataframe, and I don't know how to implement a dataframe into my function.

I have a list of values which I created by using r[[i]] <- value within a loop. Now I want to sort that list, but keep the numerical key.

> r
[[1]]
[1] 4396750

[[2]]
[1] 6340260

[[3]]
[1] 8449058

[[4]]
[1] 5676146

> r <- r[order(unlist(r))]
> r
[[1]]
[1] 4396750

[[2]]
[1] 5676146

[[3]]
[1] 6340260

[[4]]
[1] 8449058

I need some way to retain the keys, so that I know the values, from lowest to highest, are represented by keys 1,4,2,3. Then I will need to keep the keys with the lowest 3 values. So my end result should be some list or vector that gives me 1,4,2.

My example is simplified, so doing some shortcut like "just drop the highest value" won't work.

The actual code for the function is here:

knnacc <- function(e){
  dist = list()
  for(j in 1:10000) {
    dist[[j]] <- distance(TEST[["image"]][[e]], TRAIN[["image"]][[j]])
  }
  #dist <- dist[order(unlist(dist))]
  return(dist)
}

I would like to reach a point where the function returns the 20 keys associated with lowest distance out of 60,000.

Jared C
  • 314
  • 6
  • 17
  • Are you looking for `order(unlist(r))[1:3]` ? – markus Mar 21 '19 at 13:54
  • I'd suggest using more meaningful list names. Or putting it in data frame with an "id" column and a "value" column. Maybe a `list` column if there are additional list compnents you're not showing. – Gregor Thomas Mar 21 '19 at 14:12

2 Answers2

1

The 'numerical keys' are simply the index in the list. To retain the original indices in a sorted list, you might simply add names to your list elements based on those original indices.

E.g.,

r = list(4396750, 6340260, 8449058, 5676146)
#> r
#[[1]]
#[1] 4396750
#
#[[2]]
#[1] 6340260
# 
#[[3]]
#[1] 8449058
#
#[[4]]
#[1] 5676146  

names(r) <- as.character(1:length(r))

r <- r[order(unlist(r))]

#> r
#$`1`
#[1] 4396750
#
#$`4`
#[1] 5676146
#
#$`2`
#[1] 6340260
#
#$`3`
#[1] 8449058
Chris Holbrook
  • 2,231
  • 1
  • 14
  • 28
0

Not sure why you'd like a list rather than a vector. Having the following dummy variable, try:

> r
[[1]]
[1] 1

[[2]]
[1] 10

[[3]]
[1] 2

[[4]]
[1] 4

[[5]]
[1] 3

setNames(r[order(unlist(r))],order(unlist(r)))
$`1`
[1] 1

$`3`
[1] 2

$`5`
[1] 3

$`4`
[1] 4

$`2`
[1] 10
boski
  • 2,317
  • 1
  • 10
  • 27