passer plusieurs arguments à FUN de lapply (et d'autres * s'appliquent)

99

J'ai une question concernant le passage de plusieurs arguments à une fonction, lors de l'utilisation de lapplyin R.

Quand j'utilise lapply avec la syntaxe de lapply(input, myfun);- c'est facilement compréhensible, et je peux définir myfun comme ça:

myfun <- function(x) {
 # doing something here with x
}

lapply(input, myfun);

et les éléments de inputsont passés en xargument à myfun.

Mais que faire si j'ai besoin de transmettre d'autres arguments myfunc? Par exemple, il est défini comme ça:

myfun <- function(x, arg1) {
 # doing something here with x and arg1
}

Comment puis-je utiliser cette fonction en passant les deux inputéléments (en xargument) et un autre argument?

Vasily A
la source
1
Terminer les lignes d'entrée de la console R avec ";" est un signe que vous avez probablement utilisé un langage de traitement de macros dans le passé. L'argument des trois points est décrit dans la sous-section 4 de la section «Ecrire vos propres fonctions» du document «Introduction à R», sans doute le premier «Manuel» que vous devriez lire.
IRTFM

Réponses:

122

Si vous recherchez la page d'aide, l'un des arguments lapplyest le mystérieux .... Lorsque nous regardons la section Arguments de la page d'aide, nous trouvons la ligne suivante:

...: optional arguments to ‘FUN’.

Donc, tout ce que vous avez à faire est d'inclure votre autre argument dans l' lapplyappel en tant qu'argument, comme ceci:

lapply(input, myfun, arg1=6)

et lapply, reconnaissant que ce arg1n'est pas un argument avec lequel il sait quoi faire, le transmettra automatiquement myfun. Toutes les autres applyfonctions peuvent faire la même chose.

Un addendum: vous pouvez également l'utiliser ...lorsque vous écrivez vos propres fonctions. Par exemple, disons que vous écrivez une fonction qui appelle plotà un moment donné et que vous souhaitez pouvoir modifier les paramètres de tracé à partir de votre appel de fonction. Vous pouvez inclure chaque paramètre comme argument dans votre fonction, mais c'est ennuyeux. Au lieu de cela, vous pouvez utiliser ...(comme argument à la fois pour votre fonction et pour l'appel à tracer à l'intérieur), et avoir tout argument que votre fonction ne reconnaît pas être automatiquement transmis plot.

Jonathan Christensen
la source
Et si votre deuxième argument, par exemple, "arg1" est une liste qui correspond à la liste "input"? Quand j'essaye lapply (input, myfun, arg1 = input2) où input2 est une liste, il semble que lapply passe la liste entière à la fois au lieu d'élément par élément comme avec 'input'.
Alan
10
Je viens de trouver une réponse dans un autre article qui fonctionne: mapply (myfun, df $ input, df $ input2)
Alan
18

Comme suggéré par Alan, la fonction 'mapply' applique une fonction à plusieurs listes multiples ou arguments vectoriels:

mapply(myfun, arg1, arg2)

Voir la page de manuel: https://stat.ethz.ch/R-manual/R-devel/library/base/html/mapply.html

Andrew
la source
Et cela vaut la peine de mentionner outerdans la même veine, qui applique une fonction à chaque paire de valeurs dans deux arguments vectoriels. Page de manuel
ms609
11

Vous pouvez le faire de la manière suivante:

 myfxn <- function(var1,var2,var3){
      var1*var2*var3

    }

    lapply(1:3,myfxn,var2=2,var3=100)

et vous obtiendrez la réponse:

[[1]] [1] 200

[[2]] [1] 400

[[3]] [1] 600

Gpwner
la source
3
myfun <- function(x, arg1) {
 # doing something here with x and arg1
}

xest un vecteur ou d' une liste et myfunen lapply(x, myfun)est appelé pour chaque élément xséparément.

Option 1

Si vous souhaitez utiliser entier arg1dans chaque myfunappel ( myfun(x[1], arg1), myfun(x[2], arg1)etc.), utilisez lapply(x, myfun, arg1)(comme indiqué ci-dessus).

Option 2

Si vous souhaitez cependant appeler myfunchaque élément de arg1séparément à côté des éléments de x( myfun(x[1], arg1[1]), myfun(x[2], arg1[2])etc.), il n'est pas possible d'utiliser lapply. À la place, utilisez mapply(myfun, x, arg1)(comme indiqué ci-dessus) ou apply:

 apply(cbind(x,arg1), 1, myfun)

ou

 apply(rbind(x,arg1), 2, myfun).
Hanna
la source