1

Relying on the thread here, I made R "dictionary" as follows:

boxes_sent <- vector(mode="list", length=4)
boxes_sent <- c("NE01", "NE02", "NE03", "NE04")
names(boxes_sent) <- c(seq(1:4))

boxes_rcvd <- vector(mode="list", length=4)
boxes_rcvd <- c("NW01", "NW02", "NW03", "NW04")
names(boxes_rcvd) <- c(seq(from = 13, to =16))

boxes_all <- c(boxes_rcvd, boxes_sent)

> boxes_all
13     14     15     16      1      2      3      4 
"NW01" "NW02" "NW03" "NW04" "NE01" "NE02" "NE03" "NE04"

Calling names(boxes_all)[[1]] returns "13" while boxes_all[[1]] returns "NW01" both of which correspond to the first item on the list. However, I thought this would return "NE01" based on the key/value pair I established when I executed names(boxes_sent) <- c(seq(1:4)). How can I modify so that calling names(boxes_all)[[1]] returns "NE02"? In my dataset, I have 39 key/value pair for the dictionary.

I would like to use names() to do this although I attempted environment as suggested in the thread here without success:

boxes_sent<-new.env()
boxes_sent[["NE01", "NE02", "NE03", "NE04"]]<-c(seq(1:4))
boxes_rcvd <- new.env()
boxes_rcvd[["NW01", "NW02", "NW03", "NW04"]]<-c(seq(from = 13, to =16))

Error in boxes_sent[[c("NE01", "NE02", "NE03", "NE04")]] <- c(seq(1:4)) : 
  wrong args for environment subassignment

Thanks for your time and attention.

R version 3.0.3

Community
  • 1
  • 1
sedeh
  • 7,083
  • 6
  • 48
  • 65
  • Have you tried `order` or `sort`? Perhaps, I misunderstood the question. boxes_all1 <- boxes_all[order(as.numeric(names(boxes_all)))] boxes_all1[1] 1 "NE01" – akrun Jul 06 '14 at 08:15

1 Answers1

2

First thing: you don't need to specify the variable type in R. So when you have code like:

boxes_sent <- vector(mode="list", length=4)
boxes_sent <- c("NE01", "NE02", "NE03", "NE04")

You are defining boxes_sent as a list and then redefining it as a character vector afterwards. So that first line is a waste of time.

Secondly, c(seq(1:4)) is triple overkill. 1:4 gives you the sequence of numbers from one to four, returning an integer vector. It is same as calling seq(1, 4) or c(1, 2, 3, 4). You don't need all three here.

Thirdly, when you assign names to a vector, be aware that those names are stored as a character vector. (This is exactly what you want for dictionary-like behaviour.) Notice that

names(boxes_sent)
## [1] "1" "2" "3" "4"

Fourthly, if you want to use a vector as a dictionary, then you are using the wrong sort of indexing. The whole point of a dictionary is that you pass a string as an index (the 'key') and you get a value back.

So in this case, your keys are the strings "1", "2", "3", "4", "13", "14", "15", "16". So to retrieve the value "NE02", you need to pass in the key "2". That is, type boxes_all["2"].

Fifthly, messing about with environments is an advanced topic. You should almost never need to explicitly use them. For dictionary behaviour, if all your values are strings, then use a character vector. If the values have differents sizes or types, then use a list.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • This is invaluable! In my larger dataset, I used a loop and `toString()` to iterate through my data frame, convert each index to a string and return the correct value. – sedeh Jul 06 '14 at 15:41
  • 1
    If someone could point out how this could be achieved using environment, that will be an additional learning. Thanks. – sedeh Jul 06 '14 at 15:42