Storing the output of a function into a variable in R - r

I'm having trouble with storing the output of a function into a variable. I think it's best that I give some context to the problem I'm trying to work out.
Suppose that players "a" and "r" play a game of tennis, the runningScoreFn sums the pointHistory vector and puts everything together in a nice data.frame
runningScoreFn = function(pointHistory){
playerUni = c("a", "r")
cols = sapply(playerUni, function(thisPlayer){
cumsum(pointHistory == thisPlayer)
})
names(cols) = playerUni
cbind(pointHistory, as.data.frame(cols))
}
The oneEpxiermentGameFn that plays out a game of "a" v.s "r".The first player to win 4 points wins the game, but he must be ahead by at least 2 points. "r" has 60% chance of winning a point.
pRogerPoint = 0.6
oneExperimentGameFn = function(pRogerPoint){
game = c(rep("r",pRogerPoint * 100), rep("a", 100-pRogerPoint*100))
i = 4
keepGoing = TRUE
while(keepGoing){
whosePoint = sample(game, size=i, replace=TRUE)
if(sum(whosePoint=="r")-sum(whosePoint=="a")>=2){
success = TRUE
print(cbind(runningScoreFn(whosePoint),success=success))
keepGoing = FALSE
}else if(sum(whosePoint=="a")-sum(whosePoint=="r")>=2){
success = FALSE
print(cbind(runningScoreFn(whosePoint),success=success))
keepGoing = FALSE
}
i=i+1
}
}
pRogerGameFn shows the probability that Roger wins the game.
pRogerGameFn = function(pRogerPoint, NExperiments){
RogerGameFn = lapply(1:NExperiments,function(dummy){
ok=oneExperimentGameFn(pRogerPoint)
})}
Here I wish to store the output into the variable ok, but ok returns NULL. I think this has something to do with my oneExperimentGameFn.
I also tried ok = RogerGameFn, but ok also returns NULL.

there is nothing returning from the function oneExperimentGameFn.
If there is a specific value you want returned, insert a return(.) command at the end of the function (or wherever else appropriate).
If you simply want to catch the print statements, you can use capture.output(.):
ok <- capture.output(oneExperimentGameFn(pRogerPoint))

Related

Is it possible to overload functions in Scilab?

I would like to know how to overload a function in scilab. It doesn't seem to be as simple as in C++. For example,
function [A1,B1,np1]=pivota_parcial(A,B,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
//has less input/output variables//operates differently
function [A1,np1]=pivota_parcial(A,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
thanks
Beginner in scilab ....
You can accomplish something like that by combining varargin, varargout and argn() when you implement your function. Take a look at the following example:
function varargout = pivota_parcial(varargin)
[lhs,rhs] = argn();
//first check number of inputs or outputs
//lhs: left-hand side (number of outputs)
//rhs: right-hand side (number of inputs)
if rhs == 4 then
A = varargin(1); B = 0;
n = varargin(2); k = varargin(3);
np = varargin(4);
elseif rhs == 5 then
A = varargin(1); B = varargin(2);
n = varargin(3); k = varargin(4);
np = varargin(5);
else
error("Input error message");
end
//computation goes on and it may depend on (rhs) and (lhs)
//for the sake of running this code, let's just do:
A1 = A;
B1 = B;
np1 = n;
//output
varargout = list(A1,B1,np1);
endfunction
First, you use argn() to check how many arguments are passed to the function. Then, you rename them the way you need, doing A = varargin(1) and so on. Notice that B, which is not an input in the case of 4 inputs, is now set to a constant. Maybe you actually need a value for it anyways, maybe not.
After everything is said and done, you need to set your output, and here comes the part in which using only varargout may not satisfy your need. If you use the last line the way it is, varargout = list(A1,B1,np1), you can actually call the function with 0 and up to 3 outputs, but they will be provided in the same sequence as they appear in the list(), like this:
pivota_parcial(A,B,n,k,np);: will run and the first output A1 will be delivered, but it won't be stored in any variable.
[x] = pivota_parcial(A,B,n,k,np);: x will be A1.
[x,y] = pivota_parcial(A,B,n,k,np);: x will be A1 and y will be B1.
[x,y,z] = pivota_parcial(A,B,n,k,np);: x will be A1, y will be B1, z will be np1.
If you specifically need to change the order of the output, you'll need to do the same thing you did with your inputs: check the number of outputs and use that to define varargout for each case. Basically, you'll have to change the last line by something like the following:
if lhs == 2 then
varargout = list(A1,np1);
elseif lhs == 3 then
varargout = list(A1,B1,np1);
else
error("Output error message");
end
Note that even by doing this, the ability to call this functions with 0 and up to 2 or 3 outputs is retained.

Guidance on missing() in R

Suppose a function, G, takes two arguments; a and b: G(a = some number, b = some number).
Now two situations (wondering what commands to use in each case?):
1- if a user puts G(b = some number), will the if(missing(a)){do this} recognize the complete absence of a argument? AND more importantly:
2- if a user puts G(a =, b = some number), still will the if(missing(a)){do this} recognize a = but lack of some number in front of it?
Defining the function as below doesn't throw an error in both the cases:
ch <- function(a=NA,b=NA){ if(is.na(a)) return(b) else( return(a+b)) }
> ch(b=2)
[1] 2
> ch(a=,b=2)
[1] 2

How to treat i as a variable for a loop

I have a bunch of values I want to read in to an if statement in R. Namely:
year_1 , year_2
And so on.
I would like to use a for loop or a vectorisation method to test each one but I am not familiar with this in R as opposed to C++.
So I'd like to achieve something like:
for(i in 1:15) {
if(year_[i] !=NULL) {
count = count + 1
}
}
Not sure whether I am not searching for the right thing or whether R just doesn't do this sort of thing easily. I have used paste and a for loop successfully in the past to automatically name new variables but this I haven't got a hold of.
Update
Ok your answer seems to be on the right track. I should have been a bit more specific and say that I am reading the data from an excel file of parameters and using the data to produce plots. Different data sets will have different years active. The core of this problem is telling R how many years are active, starting from param$year_1 to param$year_15. So I am trying to actually read param$year_1 and so on for example, and basically check whether it is empty or not which will allow me to know how many years this particular data set is working with. When I tried mget(paste0("param$year_", 1:5))
it said the value was not found.
Update 2
I am sure the difficulty with this comes down to my description. But here is exactly what I want to produce but automated to a few lines as I know I will want to do similar operations like this is in the future. What the actual data is is irrelevant. This non automated version produces exactly what I want.
Non Automated Code
if(is.na(param$year_1[1]) == TRUE || param$year_1[1] == '') {
print("empty")
}
if(is.na(param$year_2[1]) == TRUE || param$year_2[1] == '') {
print("empty")
}
if(is.na(param$year_3[1]) == TRUE || param$year_3[1] == '') {
print("empty")
}
if(is.na(param$year_4[1]) == TRUE || param$year_4[1] == '') {
print("empty")
}
so on and so on until the final
if(is.na(param$year_15[1]) == TRUE || param$year_15[1] == '') {
print("empty")
}
It is such a simple thing to do in C++ but I have to learn it in R for the future.
It sounds like you have a list-like structure that contains names year_1, year_2, ..., year_15 and you want to check how many of these are null or have a missing first element. You could use standard indexing to limit to the elements for those years, sapply to check which are null, and sum to add up those values:
which(sapply(paste0("year_", 1:15), function(x) {
is.null(param[[x]]) || param[[x]][1] == ''
}))
# year_2 year_5 year_9 year_10 year_11 year_12 year_14 year_15
# 2 5 9 10 11 12 14 15
Data:
param <- list(ID = 1:10, year_1 = 1:5, year_2 = NULL, year_3 = 1:7, year_4 = 1:2, year_5 = NULL, year_6 = 14, year_7 = 1:3, year_8 = 1:9, year_9 = NULL, year_10 = NULL, year_11 = NULL, year_12 = NULL, year_13 = 1:7, year_14 = NULL, year_15 = NULL)

Python 3.4 help - using slicing to replace characters in a string

Say I have a string.
"poop"
I want to change "poop" to "peep".
In fact, I also want all of the o's in poop to change to e's for any word I put in.
Here's my attempt to do the above.
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
for i in range (len(y)):
if y[i] == "o":
y = y[:i] + "e"
print (y)
main()
As you can see, when you run it, it doesn't amount to what I want. Here is my expected output.
Enter a word.
>>> brother
brether
Something like this. I need to do it using slicing. I just don't know how.
Please keep your answer simple, since I'm somewhat new to Python. Thanks!
This uses slicing (but keep in mind that slicing is not the best way to do it):
def f(s):
for x in range(len(s)):
if s[x] == 'o':
s = s[:x]+'e'+s[x+1:]
return s
Strings in python are non-mutable, which means that you can't just swap out letters in a string, you would need to create a whole new string and concatenate letters on one-by-one
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
output = ''
for i in range(len(y)):
if y[i] == "o":
output = output + 'e'
else:
output = output + y[i]
print(output)
main()
I'll help you this once, but you should know that stack overflow is not a homework help site. You should be figuring these things out on your own to get the full educational experience.
EDIT
Using slicing, I suppose you could do:
def getword():
x = (input("Please enter a word."))
return x
def main():
y = getword()
output = '' # String variable to hold the output string. Starts empty
slice_start = 0 # Keeps track of what we have already added to the output. Starts at 0
for i in range(len(y) - 1): # Scan through all but the last character
if y[i] == "o": # If character is 'o'
output = output + y[slice_start:i] + 'e' # then add all the previous characters to the output string, and an e character to replace the o
slice_start = i + 1 # Increment the index to start the slice at to be the letter immediately after the 'o'
output = output + y[slice_start:-1] # Add the rest of the characters to output string from the last occurrence of an 'o' to the end of the string
if y[-1] == 'o': # We still haven't checked the last character, so check if its an 'o'
output = output + 'e' # If it is, add an 'e' instead to output
else:
output = output + y[-1] # Otherwise just add the character as-is
print(output)
main()
Comments should explain what is going on. I'm not sure if this is the most efficient or best way to do it (which really shouldn't matter, since slicing is a terribly inefficient way to do this anyways), just the first thing I hacked together that uses slicing.
EDIT Yeah... Ourous's solution is much more elegant
Can slicing even be used in this situation??
The only probable solution I think would work, as MirekE stated, is y.replace("o","e").

Lua Table Comparisons Within Tables

So I have a table that holds references to other tables like:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a[#a + 1] = b
end
Now if I want to see if a particular object is within "a" I have to use pairs like so:
local z = a.collection[ 99 ]
for i,j in pairs( a.collection ) do
if j == z then
return true
end
end
The z object is in the 99th spot and I would have to wait for pairs to iterate all the way throughout the other 98 objects. This set up is making my program crawl. Is there a way to make some sort of key that isn't a string or a table to table comparison that is a one liner? Like:
if a.collection[{z}] then return true end
Thanks in advance!
Why are you storing the object in the value slot and not the key slot of the table?
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[b] = i
end
to see if a particular object is within "a"
return a.collection[b]
If you need integer indexed access to the collection, store it both ways:
local a = newObject()
a.collection = {}
for i = 1, 100 do
local b = newObject()
a.collection[i] = b
a.collection[b] = i
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
Don't know if it's faster or not, but maybe this helps:
Filling:
local a = {}
a.collection = {}
for i = 1, 100 do
local b = {}
a.collection[b] = true -- Table / Object as index
end
Finding:
local z = a.collection[99]
if a.collection[z] then return true end
If that's not what you wanted to do you can break your whole array into smaller buckets and use a hash to keep track which object belongs to which bucket.
you might want to consider switching from using pairs() to using a regular for loop and indexing the table, pairs() seems to be slower on larger collections of tables.
for i=1, #a.collection do
if a.collection[i] == z then
return true
end
end
i compared the speed of iterating through a collection of 1 million tables using both pairs() and table indexing, and the indexing was a little bit faster every time. try it yourself using os.clock() to profile your code.
i can't really think of a faster way of your solution other than using some kind of hashing function to set unique indexes into the a.collection table. however, doing this would make getting a specific table out a non-trivial task (you wouldn't just be able to do a.collection[99], you'd have to iterate through until you found one you wanted. but then you could easily test if the table was in a.collection by doing something like a.collection[hashFunc(z)] ~= nil...)

Resources