Преобразование цикла для применения

Как в R заменить следующий код с помощью таких функций, как apply, lapply, rapply, do.call и т. д.?

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 (j in 1:ncol(p)) {
    s <- paste(p[,j], collapse=",")

Я пробовал что-то вроде:

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

Который работает. Но затем для этой части slist[[s]] <- 0 внутри того же цикла for я не знаю, что делать.

Изменить: это то, что я пытаюсь сделать. Для вектора u я создаю список всех подмножеств этого вектора. Затем для каждого подмножества я присваиваю его s, а затем использую строку s в качестве имени элемента в slist. Немного странно, я знаю, но это для домашнего задания. Для приведенного выше кода это будут первые 5 элементов slist:

 > slist
 $`10`
 [1] 0

 $`11`
 [1] 0

 $`12`
 [1] 0

 $`10,11`
 [1] 0

 $`10,12`
 [1] 0

Да, я просто пытаюсь научиться правильно использовать приложения и прочее.


person Crystal    schedule 15.11.2011    source источник
comment
Ваш цикл for создает довольно необычный список. Возможно, вы хотите объяснить, что вы на самом деле пытаетесь сделать?   -  person Andrie    schedule 16.11.2011
comment
Хорошо, готово! Я отредактировал исходный пост.   -  person Crystal    schedule 16.11.2011


Ответы (3)


Вот одно из решений:

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

ОБНОВЛЕНИЕ Опубликовано одновременно с @djhurio, оно очень похоже, но я позволил себе изменить использование combn, чтобы оно обрабатывало u длины 1, как указал @djhurio.

person Tommy    schedule 15.11.2011
comment
Могу ли я получить репутацию за увеличение использования *apply на единицу? indvec <- unlist(lapply( sapply(1:3, combn, x=u) , function(z) apply(z, 2, paste, collapse=",") ) ) - person IRTFM; 16.11.2011
comment
Ну, вы получили комментарий от меня. Тогда жалуйтесь мейнтейнерам stackoverflow, что комментарии должны давать очки репутации ;-) - person Tommy; 16.11.2011

Решение с использованием одного apply и одного lapply. Работает также, если 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
person djhurio    schedule 15.11.2011

Еще одно решение без необходимости использования анонимных функций. mapply векторизует combn, а rapply рекурсивно обходит список комбинаций, сворачивая их с помощью ,.

rapply(mapply(combn, list(u), seq_along(u), simplify = F), paste, collapse = ",")
person Ramnath    schedule 15.11.2011