Ongebruikte argumenten in R

In R, is het mogelijk om de software het feit te laten negeren dat er ongebruikte argumenten zijn gedefinieerd wanneer een module wordt uitgevoerd?

Ik heb bijvoorbeeld een module multiply(a,b), die het product van aen bretourneert. Ik krijg een foutmelding als ik de module als volgt aanroep:

multiply(a=20,b=30,c=10)

Het lijkt een beetje onnodig om hier een fout op terug te geven, aangezien de vereiste invoer aen bis opgegeven. Is het mogelijk om dit slechte gedrag te vermijden?

Een gemakkelijke oplossing zou zijn om gewoon te stoppen met het specificeren van c, maar dat geeft geen antwoord op waarom Rzich zo gedraagt. Is er een andere manier om dit op te lossen?


Antwoord 1, autoriteit 100%

Verander de definitie van vermenigvuldigen om aanvullende onbekende argumenten op te nemen:

multiply <- function(a, b, ...) {
  # Original code
}

Antwoord 2, autoriteit 27%

Het R.utils-pakket heeft een functie genaamd doCall die lijkt op do.call, maar het geeft geen foutmelding als ongebruikte argumenten worden doorgegeven.

multiply <- function(a, b) a * b
# these will fail
multiply(a = 20, b = 30, c = 10)
# Error in multiply(a = 20, b = 30, c = 10) : unused argument (c = 10)
do.call(multiply, list(a = 20, b = 30, c = 10))
# Error in (function (a, b)  : unused argument (c = 10)
# R.utils::doCall will work
R.utils::doCall(multiply, args = list(a = 20, b = 30, c = 10))
# [1] 600
# it also does not require the arguments to be passed as a list
R.utils::doCall(multiply, a = 20, b = 30, c = 10)
# [1] 600

Antwoord 3, autoriteit 22%

Een benadering (waarvan ik me niet kan voorstellen dat het een goede programmeerpraktijk is) is om de ...toe te voegen die traditioneel wordt gebruikt om argumenten die in de ene functie zijn opgegeven, door te geven aan een andere.

> multiply <- function(a,b) a*b
> multiply(a = 2,b = 4,c = 8)
Error in multiply(a = 2, b = 4, c = 8) : unused argument(s) (c = 8)
> multiply2 <- function(a,b,...) a*b
> multiply2(a = 2,b = 4,c = 8)
[1] 8

Je kunt meer lezen over ...is bedoeld voor gebruik hier


Antwoord 4, autoriteit 17%

Je zou punten kunnen gebruiken: ...in je functiedefinitie.

myfun <- function(a, b, ...){
  cat(a,b)
}
myfun(a=4,b=7,hello=3)
# 4 7

Antwoord 5, autoriteit 7%

Ik had hetzelfde probleem als jij. Ik had een lange lijst met argumenten, waarvan de meeste niet relevant waren. Ik wilde ze niet hard coderen. Dit is wat ik bedacht

library(magrittr)
do_func_ignore_things <- function(data, what){
    acceptable_args <- data[names(data) %in% (formals(what) %>% names)]
    do.call(what, acceptable_args %>% as.list)
}
do_func_ignore_things(c(n = 3, hello = 12, mean = -10), "rnorm")
# -9.230675 -10.503509 -10.927077

Antwoord 6

R heeft een functie prod() die vermenigvuldigen heel goed doet. Het voorbeeld dat de vrager gaf, werkt prima met de prod()-functie zonder een fout te retourneren.`

prod(a=20,b=30,c=10)
 # 6000

In elk geval is een gemarkeerde fout een kans om deze te corrigeren, dus geen slecht gedrag.


Antwoord 7

Aangezien er al een aantal antwoorden zijn die rechtstreeks op de vraag ingaan, en R vaak wordt gebruikt door technisch bekwame niet-programmeurs, zal ik snel uitleggen waarom de fout bestaat, en afraden om tijdelijke oplossingen te onderdrukken.

Het aantal parameters is een belangrijk aspect bij het definiëren van een functie. Als het aantal parameters niet overeenkomt, is dat een goede indicatie dat er een mismatch is tussen de bedoeling van de beller en wat de functie gaat doen. Om deze reden zou dit een compilatiefout zijn in veel programmeertalen, waaronder Java, Python, Haskell en vele andere. Sterkere typecontrole in veel van deze talen zal ook fouten veroorzaken als typen niet overeenkomen.

Naarmate een programma groter wordt en de code ouder wordt, wordt het moeilijker om te zien of dit soort mismatches bedoeld zijn of echte bugs zijn. Dit is de reden waarom een idee van “schone code” – eenvoudig te lezen code zonder fouten of waarschuwingen – vaak een standaard is waar professionele programmeurs naar toe werken.

Daarom raad ik aan de code te herwerken om de onnodige parameter te verwijderen. Het zal in de toekomst eenvoudiger te begrijpen en te debuggen zijn voor uzelf en anderen.

Natuurlijk begrijp ik dat R-gebruikers vaak werken aan kleine scripts met een beperkte levensduur, en de gebruikelijke afwegingen van grote software-engineeringprojecten zijn niet altijd van toepassing. Misschien was het voor je snelle script, dat maar een week zal worden gebruikt, logisch om de fout gewoon te onderdrukken. Het wordt echter algemeen waargenomen (en ik heb gezien in mijn eigen ervaring) dat wat code doorstaat, zelden duidelijk is op het moment van schrijven. Als u open wetenschap nastreeft en uw code en gegevens publiceert, is het vooral nuttig dat die code in de toekomst nuttig is voor anderen, zodat zij uw resultaten kunnen reproduceren.

Other episodes