0

I am trying to create a list of requests called requests. I have a list of hundreds of products, but I simplify for this example code.

products <- list()
products[[1]] <- c("77295T", "67619Q", "9528QR")
products[[2]] <- c("B7295T", "676193")
requests <- vector("list",length(products[[1]]))
length(requests)
i <- 1
for (i in 1:(length(products[[1]])))  {
    requests[[i]] <- cat('"',noquote(products[[1]][[i]]),'~XPORT"', sep = '')  
   }

results in:

"77295T~XPORT""67619Q~XPORT""9528QR~XPORT"

The end result I am looking for is a request list of length 3 with the following three elements:

requests[[1]] 
"77295T~XPORT"

requests[[2]]
"67619Q~XPORT"

requests[[3]]
"9528QR~XPORT"

Background: Eventually I want requests to be a nested list (a list of lists); in my dataset products is a list, so that is why I provide products[[2]], even though my question relates to just iterating over products[[1]]. Replacingproducts[[1]]` with an equivalent products1 also creates the same output. That code is here:

products1 <- c("77295T", "67619Q", "9528QR")
i <- 1
for (i in 1:(length(products1))) {
  requests[[i]] <- cat('"',noquote(products1[[i]]),'~XPORT"', sep = '')  
  }

This more simple code provides the same results:

"77295T~XPORT""67619Q~XPORT""9528QR~XPORT"

I do realize that the for loop I called may not be necessary. I am trying to gradually learn how to "vectorize" my R code. Any suggestion for further vector-elegance in this code would be appreciated.

4
  • 2
    Probably requests <- as.list(paste(products[[1]], "XPORT", sep="~")) is the simplest answer. Commented Jun 1, 2017 at 14:25
  • 1
    lapply(products[[1]], function(x){ paste0(x, "~XPORT")}) should also work Commented Jun 1, 2017 at 14:27
  • @lmo you mean, this code without the loop, right? That does the trick. Commented Jun 1, 2017 at 14:38
  • 1
    Yes. A loop is not needed with that code. In this instance, paste does the work under the hood. Commented Jun 1, 2017 at 14:40

2 Answers 2

3

I guess what you are looking for is this:

requests <- lapply(products[[1]], function(x){paste0(x, "~XPORT")})
requests
# [[1]]
# [1] "77295T~XPORT"
#
# [[2]]
# [1] "67619Q~XPORT"
#
# [[3]]
# [1] "9528QR~XPORT"

And if you wish to do this to all vectors in products, I would use a loop:

request <- list()
for(i in 1:length(products)){
   request[[i]] <- lapply(products[[i]], function(x){paste0(x, "~XPORT")})
}

I'm sure this is just one of many ways to accomplish this.

Edit

An alternative to the above without any loops, would be to use sapply instead of for

sapply(products, function(y){
  lapply(y, function(x) paste0(x, "~XPORT"))
})
Sign up to request clarification or add additional context in comments.

3 Comments

Both parts of this code works. Thank you. I am wondering if there is a way to avoid the second loop. I tried req4 <- lapply(prods, function(x){paste0(x, "~XPORT")}), but that doesn't generate a nested list, just a list of two, where the first looks like this: "77295T~XPORT" "67619Q~XPORT" "9528QR~XPORT"
@mrlcpa I just added an alternative that works without using a loop
The alternative without loops works, thank you. When I replace sapply with lapply, the resulting all.equal(request1,request2) brings back TRUE. So I guess in this case they function the same.
0

As suggested by Ken ,to get the nested list without using the loop, as.list() might be helpful on this case.

products <- list()
products[[1]] <- c("77295T", "67619Q", "9528QR")
products[[2]] <- c("B7295T", "676193")
requests <- lapply(products, function(x){ as.list(paste0(x, "~XPORT"))})
requests

[[1]]
[[1]][[1]]
[1] "77295T~XPORT"

[[1]][[2]]
[1] "67619Q~XPORT"

[[1]][[3]]
[1] "9528QR~XPORT"


[[2]]
[[2]][[1]]
[1] "B7295T~XPORT"

[[2]][[2]]
[1] "676193~XPORT"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.