увеличивать несколько аргументов в lapply

Есть ли способ увеличить два аргумента в функции lapply? Например

test <- function(pos,value){
   list[pos,value]
}

data=c(1,4,32,54) #not global
lapply(X=1:length(data),test, value=data[X])#this is the idea but the code doesnt work

Результат будет list(list(1,1),list(2,4),list(3,32),list(4,54))

Другой пример:

test <- function(pos,value,value2){
   list(pos,value,value2)
}

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global
lapply(X=1:length(data),test, value=data[X], value2=data2[X]) #this is the idea but the code doesn't work

Результат будет list(list(1,1,2),list(2,4,2),list(3,32,6),list(4,54,21))

Это тоже может помочь. Я в значительной степени пытаюсь превратить цикл for в lapply.

test <- function(pos,value,value2){
   list(pos,value,value2)
}

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global
for(i:length(data)){
  result=list(result,test(i,data[i],data2[i]))
}

Поскольку переменные не являются глобальными, я не могу использовать тестовую функцию как

test <- function(pos){
   list(pos,data[pos],data2[pos])
}

Я знаю, что есть более простой способ написать этот код, чтобы добиться того же. Но я ищу способ специально увеличить две переменные или использовать увеличенное значение в аргументе. Переменные, используемые в примерах, не являются глобальными, поэтому я не могу использовать их в функции, и необходимо использовать функцию lapply. В кодах линии не работают, это просто демонстрация концепции того, что я пытаюсь сделать. Спасибо.

Редактировать

Итак, узнав о функции mapply. Я понял, что хочу создать функцию lapply, которая действует как mapply


person Nikita Belooussov    schedule 04.11.2019    source источник
comment
что это за объект data?   -  person Sotos    schedule 04.11.2019
comment
@Sotos, это был список. Извините, я привык писать на Python. Думаю я исправил все правильно   -  person Nikita Belooussov    schedule 04.11.2019
comment
Вы можете использовать Map, Map(c, seq_along(data), data, data2)   -  person Ronak Shah    schedule 04.11.2019
comment
@RonakShah Мне нужно использовать функцию lapply. Проблема, над которой я работаю, немного другая. Я просто упростил его для этого случая.   -  person Nikita Belooussov    schedule 04.11.2019
comment
@NikitaBelooussov Я думаю, вы имеете в виду вектор ...._ 1_ = список ... c(1, 2, 3) = вектор ...   -  person Sotos    schedule 04.11.2019
comment
@Sotos да, извините, я все еще привыкаю ко всем именам и синтаксису, извините. Если я неправильно обозначил ожидаемый результат, не стесняйтесь его исправлять. Я почти уверен, что на этот раз понял все правильно.   -  person Nikita Belooussov    schedule 04.11.2019
comment
Я думаю, вам нужно включить лучший пример, включая то, что вы можете / не можете делать.   -  person Ronak Shah    schedule 04.11.2019
comment
@RonakShah, можете ли вы сказать мне, какие части вы находите неясными, чтобы я мог придумать лучший пример или прояснить его в вопросе. Прямо сейчас я ни о чем не могу думать и знаю, что это только потому, что я это написал.   -  person Nikita Belooussov    schedule 04.11.2019
comment
Зачем тебе lapply()? Все, что можно сделать в *apply(), можно сделать с помощью обычного цикла. Кроме того, предложение Ронака о Map(list, var1, var2, ...) будет соответствовать вашему выводу.   -  person Cole    schedule 04.11.2019
comment
@Cole У меня есть более крупный код, который я пытаюсь векторизовать, и он в основном работает, за исключением этой части. Если невозможно создать lapply, которое функционирует как mapply, у меня есть цикл for, который я могу использовать.   -  person Nikita Belooussov    schedule 04.11.2019
comment
Использование lapply() - это просто скрытый цикл. Обычно это эквивалентно res<- list(); for (element in elements) {res[[element]] <- f_x(element)}, где elements - первый аргумент в lapply(), а fx() - вызов функции.   -  person Cole    schedule 04.11.2019
comment
И mapply(..., simplify = F) обычно эквивалентен, для векторов x и y каждый длиной 2 равен res <- list(); for (i in 1:2) {res[[i]] <- fx(x[i], y[I])}   -  person Cole    schedule 04.11.2019


Ответы (3)


Думаю, mapply - лучший выбор, чем lapply в вашем случае.

Предполагая, что у вас есть переменное количество входных аргументов, вы можете переписать test как

test <- function(pos,...){
  list(pos, ...)
}

Для ввода в ваш пример

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global

используя mapply, вы можете добраться туда:

mapply(test, seq_along(data), data, data2, SIMPLIFY = F)
person ThomasIsCoding    schedule 04.11.2019
comment
Да, я думаю, это эквивалент того, что я ищу. Вы можете придумать способ создать лаппли. Что делает то же самое? Или вы думаете, что это невозможно? - person Nikita Belooussov; 04.11.2019
comment
Я не думаю, что можно было бы проиндексировать data при использовании lapply, поскольку вы не можете отслеживать итерацию, согласно моим ограниченным знаниям lapply функции @NikitaBelooussov - person ThomasIsCoding; 04.11.2019

Использование оператора присваивания «‹ - »:

num_vec <- c(1, 4, 32, 54)

num_vec2 <- c(2, 6, 3, 21)

# Using lapply: 

lapply(seq_along(num_vec), function(x){return(c(x, num_vec[x], num_vec2[x]))})

Использование оператора присваивания "=":

num_vec = c(1, 4, 32, 54)

num_vec2 = c(2, 6, 3, 21)

# Using lapply: 

lapply(seq_along(num_vec), function(x){return(c(x, num_vec[x], num_vec2[x]))})

В приведенном выше случае оператор присваивания не имеет значения и не относится к локальному или глобальному присваиванию.

В ответ на дополнительный запрос о желании получить элементы на основе значения в любом из векторов:

num_vec = c(1, 4, 32, 54)


num_vec2 = c(2, 6, 3, 21)

test <- function(num_vec, num_vec2, val) {
  if (!hasArg(val)) {
    val <- 1:max(c(num_vec, num_vec2))
  } else{
    as.numeric(c(val))
  }

  lapply(seq_along(num_vec),

         function(x) {
           return(c(x, num_vec[x], num_vec2[x]))
         })[ifelse(
           val %in% num_vec &

             !(val %in% num_vec2),

           which(num_vec %in% val),

           ifelse(
             !(val %in% num_vec2) &

               !(val %in% num_vec2),

             0,

             ifelse(
               val %in% num_vec &

                 val %in% num_vec2,

               c(which.min(
                 which(val %in% num_vec), which(val %in% num_vec2)
               ),

               which.max(
                 which(val %in% num_vec), which(val %in% num_vec2)
               )),

               which(val %in% num_vec2)
             )
           )
         )]

}

test(num_vec, num_vec2, 54)
person hello_friend    schedule 04.11.2019
comment
нет, вы можете назначить num_vec локально внутри функции, и это тоже будет работать. Однако в приведенном выше коде мы используем его для итерации, поэтому присвоение его перед функцией более читабельно, а затем скажем: lapply (seq_along (num_vec ‹- c (1,4,32,54)), function (x) { return (c (x, num_vec ‹- c (1,4,32,54) [x]))}) - person hello_friend; 04.11.2019
comment
Также, если вы нашли мой ответ удовлетворительным, пожалуйста, не забудьте, что он понравится, и если он решил вашу проблему, не забудьте принять его. - person hello_friend; 04.11.2019
comment
@NikitaBelooussov, пожалуйста, посмотрите мой отредактированный ответ выше. - person hello_friend; 04.11.2019
comment
Ага. Я собираюсь протестировать это, так как я могу просто что-то неправильно понять, но эта часть num_vec ‹- c (1,4,32,54) [x] заставляет меня думать, что если num_vec не является глобальным, поэтому функция, определенная в lapply, не может получить к нему доступ. Тогда num_vec [x] работать не будет. - person Nikita Belooussov; 04.11.2019
comment
Ага. Я только что протестировал. в моем случае это не сработало. Позвольте мне придумать способ лучше отредактировать примеры кода в моем вопросе, поскольку я думаю, что большинство людей находят проблемы с пониманием того, что я ищу. И это в основном из-за того, что код в вопросе не демонстрирует его полностью должным образом. - person Nikita Belooussov; 04.11.2019
comment
Вы используете примеры, которые я привел в своем ответе? - person hello_friend; 04.11.2019
comment
так что я напрямую, и если вы используете =, как во втором примере, это не работает, и я думаю, что это более правильно представляет мою проблему. Итак, как бы я это сделал, не меняя его на ‹-. Я использовал этот веб-сайт для его запуска. rdrr.io/snippets - person Nikita Belooussov; 04.11.2019
comment
Я также запустил его с оператором присваивания = на этом веб-сайте, и он сработал. - person hello_friend; 04.11.2019
comment
да извините, у меня была опечатка, которую я не заметил - person Nikita Belooussov; 04.11.2019

Просто добавив к ответу @hello_friend, вы можете передать аргументы функции, используя lapply. Из вопроса я понимаю, что вы хотите передать функции более одного аргумента. Приведенный ниже код пытается это сделать. Пожалуйста, посмотрите.

vec1 <- c(1, 3, 5, 7)

vec2 <- c(2, 4, 6, 8)

test <- function(pos, vec_arg1, vec_arg2){
  return(c(pos, vec_arg1[pos], vec_arg2[pos]))
}
# Using lapply: 

lapply(seq_along(num_vec), test, vec1, vec2)
person Kumar Manglam    schedule 04.11.2019
comment
Я думаю, что это ближе, но могу ли я ввести только значение в этой позиции вместо всего вектора - person Nikita Belooussov; 04.11.2019
comment
Не уверен, что вы имеете в виду, но, судя по вашему редактированию, может оказаться mapply решением. - person Kumar Manglam; 04.11.2019
comment
Ага. Я не знал о маппли. Теперь, зная об этом, я хочу, чтобы lapply функционировал как mapply, но я предполагаю, что это невозможно. - person Nikita Belooussov; 04.11.2019