4

In R, how do you replace the following code using functions like apply, lapply, rapply, do.call, etc.?

u <- 10:12
slist <- list()

for (i in 1:length(u)) {
  p <- combn(u, i) 
  for (j in 1:ncol(p)) {
    s <- paste(p[,j], collapse=",")
    slist[[s]] <- 0
  }
}


For this part:

  for (j in 1:ncol(p)) {
    s <- paste(p[,j], collapse=",")

I tried something like:

  s <- apply(p, 2, function(x) paste(x, collapse=","))

Which works. But then for that slist[[s]] <- 0 part inside that same for-loop, I don't know what to do.

Edit: This is what I'm trying to do. For the vector u, I'm producing a list of all the subsets in that vector. Then for each subset, I'm assigning it to s, then using the string s as the name of an element in slist. Kind of strange, I know, but it's for a homework assignment. For the code above, this would be the first 5 elements of slist:

 > slist
 $`10`
 [1] 0

 $`11`
 [1] 0

 $`12`
 [1] 0

 $`10,11`
 [1] 0

 $`10,12`
 [1] 0

Yeah, I'm just trying to learn how to use apply and stuff properly.

Andrie
  • 176,377
  • 47
  • 447
  • 496
Crystal
  • 191
  • 5
  • 10

3 Answers3

4

Here's one solution:

n <- unlist(lapply(seq_along(u), function(i) {
  apply(combn(length(u),i),2, function(x) paste(u[x], collapse=','))
}
))

slist <- list()
slist[n] <- 0

UPDATE Posted at the same time as @djhurio, it is very similar, but I took the liberty of changing the use of combn so it handles u of length 1, as @djhurio pointed out.

Tommy
  • 39,997
  • 12
  • 90
  • 85
  • 3
    Can I get any rep for increasing the use of *apply's by one? `indvec <- unlist(lapply( sapply(1:3, combn, x=u) , function(z) apply(z, 2, paste, collapse=",") ) )` – IRTFM Nov 15 '11 at 22:04
  • 1
    Well, you got a comment upvote from me - Then complain to the stackoverflow maintainers that comment upvotes should give rep points ;-) – Tommy Nov 15 '11 at 22:15
3

Solution using one apply and one lapply. Works also if length(u)==1.

# Define function to create combinations
f1 <- function(y, i) {
  if (length(y)==1) as.character(y) else {
    p <- combn(y, i)
    apply(p, 2, function(x) paste(x, collapse=","))
  }
}

# Initial vector
u <- 10:12

# Character vector with all posible combinations
l <- unlist(lapply(1:length(u), f1, y=u))
l

# Create list with 0 values and same length as l
slist <- as.list(rep(0, length(l)))

# Assign names to the list objects
names(slist) <- l

slist
djhurio
  • 5,437
  • 4
  • 27
  • 48
1

Another solution without the need for anonymous functions. The mapply vectorizes combn, while rapply traverses the combination list recursively, collapsing them using ,.

rapply(mapply(combn, list(u), seq_along(u), simplify = F), paste, collapse = ",")
Ramnath
  • 54,439
  • 16
  • 125
  • 152