How to Assign from a Function with Multiple Outputs

How to assign from a function which returns more than one value?

(1) list[...]<- I had posted this over a decade ago on r-help. Since then it has been added to the gsubfn package. It does not require a special operator but does require that the left hand side be written using list[...] like this:

library(gsubfn)  # need 0.7-0 or later
list[a, b] <- functionReturningTwoValues()

If you only need the first or second component these all work too:

list[a] <- functionReturningTwoValues()
list[a, ] <- functionReturningTwoValues()
list[, b] <- functionReturningTwoValues()

(Of course, if you only needed one value then functionReturningTwoValues()[[1]] or functionReturningTwoValues()[[2]] would be sufficient.)

See the cited r-help thread for more examples.

(2) with If the intent is merely to combine the multiple values subsequently and the return values are named then a simple alternative is to use with :

myfun <- function() list(a = 1, b = 2)

list[a, b] <- myfun()
a + b

# same
with(myfun(), a + b)

(3) attach Another alternative is attach:

attach(myfun())
a + b

ADDED: with and attach

How to assign from a function with multiple outputs?

I found list2env ideal for what you're describing; the trickiest bit, for me, was working out what to give for the env parameter:

f=function(){
list(a=1,b="my string")
}

ret=f()
list2env(ret,env=environment())
#a=ret$a;b=ret$b #Same as previous line

print(a);print(b) #1 and "my string"

How do I assign outputs of a function with multiple outputs to different varables in Swift?

I believe you are talking about tuples here. Here is an example.

func blah(x: Int, y: Int) -> (a: Int, b: Int) {
return (x,y)
}

let output = blah(1,1)

print(output.0, output.b) // You can access them using indices or the variable names. If they don't have names, you'll have to use indices.

And about passing the tuple as input, it was deprecated in Swift 2 something and later removed in Swift 3. So you have no other way than to pass the parameters individually.

blah(output.a, output.b)

Or you can even use multiple variables as shown in @vacawama answer.

R: how to get a user-defined function to return multiple outputs?

It's really very easy. Just return a list:

user <- function(x){a <- x+1; a <- a+0.1; b <- a*-1; return( list(a,b, absum=sum(a,b) )) }

I disagree with Dason at least on my first reading. This is exactly the R-way to do it. On my second reading I think he was trying to get across the notion that functions have environments and that you cannot expect variables to persist outside of them unless they are returned in a defined structure. Lists are the typical structure for returning more complex objects. Might be better to return a named list so that the indexing conventions might be available.

Assign multiple results from function when grouping

If you make your function return a list you only need to call

dt[, myRegr(x, y), by = a]
# a minX minY k m r2
#1: 0 12 1 -0.3095238 8.285714 0.3176692
#2: 1 31 2 -1.0000000 37.000000 0.2500000

With

myRegr = function(x, y) {
regr = lm.fit(cbind(1, x), y)
coefs = regr$coef
k = coefs[[2]]
m = coefs[[1]]
r2 = 1 - var(regr$residuals) / var(y)

return (list(# minX = min(x),
# minY = min(y),
k = k,
m = m,
r2 = r2))
}

update

You might subset for x and y values and then join with the result of your function

result <- dt[dt[, .I[which.min(time)], by = a]$V1, .(a, x, y)]
result <- result[dt[, myRegr(x, y), by = a], on = .(a)]
result
# a x y k m r2
#1: 0 12 3 -0.3095238 8.285714 0.3176692
#2: 1 34 4 -1.0000000 37.000000 0.2500000

How to get a single output from a function with multiple outputs?

You have two broad options, either:

  1. Modify the function to return either or both as appropriate, for example:

    def divide(x, y, output=(True, True)):
    quot, rem = x // y, x % y
    if all(output):
    return quot, rem
    elif output[0]:
    return quot
    return rem

    quot = divide(x, y, (True, False))
  2. Leave the function as it is, but explicitly ignore one or the other of the returned values:

    quot, _ = divide(x, y)  # assign one to _, which means ignore by convention
    rem = divide(x, y)[1] # select one by index

I would strongly recommend one of the latter formulations; it's much simpler!

Efficient assignment of a function with multiple outputs in dplyr mutate or summarise

The tie package from Romain Francois can do this very neatly

devtools::install_github("romainfrancois/tie")
library('tidyverse')
library('tie')

tmp <- mtcars %>%
group_by(cyl) %>%
bow( tie(min, median, mean, max) := summary(mpg)[c(1,3,4,6)] )

Note the use of := rather than =.

This issue of using functions that return vectors (not scalars) inside summarise is considered by the tidyverse team here https://github.com/tidyverse/dplyr/issues/154 and in further posts referenced within.

Assigning output of a function to two variables in R

This may not be as simple of a solution as you had wanted, but this gets the job done. It's also a very handy tool in the future, should you need to assign multiple variables at once (and you don't know how many values you have).

Output <- SomeFunction(x)
VariablesList <- letters[1:length(Output)]
for (i in seq(1, length(Output), by = 1)) {
assign(VariablesList[i], Output[i])
}

Loops aren't the most efficient things in R, but I've used this multiple times. I personally find it especially useful when gathering information from a folder with an unknown number of entries.

EDIT: And in this case, Output could be any length (as long as VariablesList is longer).

EDIT #2: Changed up the VariablesList vector to allow for more values, as Liz suggested.

VB function with multiple output - assignment of results

For future readers, VB.NET 2017 and above now supports value tuples as a language feature. You declare your function as follows:

Function ColorToHSV(clr As System.Drawing.Color) As (hue As Double, saturation As Double, value As Double)
Dim max As Integer = Math.Max(clr.R, Math.Max(clr.G, clr.B))
Dim min As Integer = Math.Min(clr.R, Math.Min(clr.G, clr.B))

Dim h = clr.GetHue()
Dim s = If((max = 0), 0, 1.0 - (1.0 * min / max))
Dim v = max / 255.0

Return (h, s, v)
End Function

And you call it like this:

Dim MyHSVColor = ColorToHSV(clr)
MsgBox(MyHSVColor.hue)

Note how VB.NET creates public property named hue inferred from the return type of the called function. Intellisense too works properly for these members.

Note however that you need to target .NET Framework 4.7 for this to work. Alternately you can install System.ValueTuple (available as NuGet package) in your project to take advantage of this feature.

Handle multiple returns from a function in Python

Technically, every function returns exactly one value; that value, however, can be a tuple, a list, or some other type that contains multiple values.

That said, you can return something that uses something other than just the order of values to distinguish them. You can return a dict:

def testFunction(...):
...
return dict(diff1=..., diff2=..., sameCount=..., venn=...)

x = testFunction(...)
print(x['diff1'])

or you can define a named tuple:

ReturnType = collections.namedtuple('ReturnType', 'diff1 diff2 sameCount venn')

def testFunction(...):
...
return ReturnType(diff1=..., diff2=..., sameCount=..., venn=...)

x = testFunction(...)
print(x.diff1) # or x[0], if you still want to use the index


Related Topics



Leave a reply



Submit