Use for loop with if else statement in R - r

I am trying to create a for loop with an if else statement. My code looks the following:
for(i in 1:length(assignmentlist[,1]))
{if assignmentlist$Approve[i]=="1"
{ApproveAssignment(assignments=assignmentlist$AssignmentId[i],sandbox=T)}
else {RejectAssignment(assignments=assignmentlist$AssignmentId[i],sandbox=T)}}
whereas the "assignmentlist" looks like the following
> assignmentlist
AssignmentId Approve
1 5135 1
2 8963 0
3 6823 0
4 3287 1
Basically I would like to execute the "ApproveAssignment" function for all the entries that have a "1" in the "Approve" collumn. The problem is, that I would like to use the same index (the same i) inside the ApproveAssignment function. Unfortunately, this does not seem to work. Does anyone has a gentle way to avoid this problem?
Edit: The Approve Assignment function is a function that approves a certain assignment of Mechanical Turk over an API and is part of the MTurkR package
Any help yould be appreciated very much!

I don't get the point because the "i" of youy loop can be directly used in your function:
ApproveAssignment <- function(assignments=NULL, sandbox=NULL) cat(i, "was approved\n")
RejectAssignment <- function(assignments=NULL, sandbox=NULL) cat(i, "was rejected\n")
for(i in 1:length(assignmentlist[,1])){
if (assignmentlist$Approve[i]=="1")
ApproveAssignment(assignments=assignmentlist$AssignmentId[i],sandbox=T)
else
RejectAssignment(assignments=assignmentlist$AssignmentId[i],sandbox=T)
}

If, which I assume given I you want to use it inside it, you are the author of ApproveAssignment, you should hand the index over to the function as an additional argument.
ApproveAssignment <- function(assignments, sandbox, index) { ... }

ApproveAssignment and RejectAssignment internally loop through a vector of AssignmentIds to make an assignment-specific call to the API, so all you have to do is feed it a vector of AssignmentIds, no need for the loop or any of the conditionals.
ApproveAssignment(assignments=assignmentlist$AssignmentId[assignmentlist$Approve==1],sandbox=T)
RejectAssignment(assignments=assignmentlist$AssignmentId[!assignmentlist$Approve==1],sandbox=T)

Related

Define a piecewise function in Scilab given the variable as a vector

Hi I have the following code in Scilab:
>Tc=0;
>Tm=1;
>Tf=1800;
>t=(Tc:1:Tf)';
where t is a vector of 1800 components.
And I am asked to do a piecewise function that satisfies certain conditions,
My first try was to do something on the line of
> function vg=simula_vg(t,Tcg,Tfg,Ag)
> if (t<Tcg | t>Tfg) then
> vg=0;
> else
> vg=Ag*Ag*(1-cos(2*%pi*(t-Tcg)/(Tfg-Tcg)));
>end
>endfunction
But it doesnt work as I am asking it to compare vector and scalars.
Then I tried to write this
>for i=[Tc:1:Tf]
>function vg=simula_vg(t,Tcg,Tfg,Ag)
> vg(t<Tcg)=0
>vg(t>Tfg)=0
>vg((Tcg<=t)&(t<=Tfg))=sin(t(i))
>endfunction
>end
But I doesnt work either and I have run out of ideas, is there anything else I can do? All the variables are well defined
>vm=10;
>Ag=2;
>Tcg=200;
>Tfg=400;
>Ar=2;
>Tcr=1000;
>Tfr=1500;
>As=2;
>fs=0.0008;
>h=20;
>d=0.6;
There are more because there are more functions similar to that one that I have to define and I dont know how. Any suggestions on how to do it?
You can do it like this, where the zero values are defined afterwards:
function vg=simula_vg(t,Tcg,Tfg,Ag)
vg=Ag*Ag*(1-cos(2*%pi*(t-Tcg)/(Tfg-Tcg)));
vg(t<Tcg|t>Tfg)=0;
endfunction
Ag=2;
Tcg=200;
Tfg=400;
Tc=0;
Tm=1;
Tf=1800;
t=Tc:1:Tf;
vg = simula_vg(t,Tcg,Tfg,Ag);
plot(t,vg)

R function to check each element and its related children elements to add a result to a list

Suppose we have given dataframe in R. By 0--7, it means it is taking integer values from 0-7 i.e. 0,1,2,3,4,5,6,7.
I am interested in making a function such that
If a[1,1]>alpha, it goes and checks its children i.e. 0--7 consists of a[1,2] and a[2,2].
So,
{a[2,1]>alpha
{a[4,1]>alpha
{a[5,1]>alpha
ps=list.append(0)
else ps=list.append(1)
}}}
Here, alpha is a a threshold. The ps is appended from values of 0 to 15 based on this criteria.
My code is
{for (i in 1:2)
{ if (a[j,i]>alpha)
{if (i%%2==1}
{j=j*2
if (a[j,i]>alpha
###here i want to go recursively i think and where and how should i add append values to the list
if a[j,i+1]>alpha}
if{i%%2==0}
{}
}}
I am stuck and confused at the same time. Any help or advices would be greatly appreciated.
Thanks

Vectorized Operation in R causing problems with custom function

I'm writing out some functions for Inventory management. I've recently wanted to add a "photo url column" to my spreadsheet by using an API I've used successfully while initially building my inventory. My Spreadsheet header looks like the following:
SKU | NAME | OTHER STUFF
I have a getProductInfo function that returns a list of product info from an API I'm calling.
getProductInfo<- function(barcode) {
#Input UPC
#Output List of product info
CallAPI(barcode)
Process API return, remove garbage
return(info)
}
I made a new function that takes my inventory csv as input, and attempts to add a new column with product photo url.
get_photo_url_from_product_info_output <- function(in_list){
#Input GetProductInfo Output. Returns Photo URL, or nothing if
#it doesn't exist
if(in_list$DisplayStockPhotos == TRUE){
return(in_list$StockPhotoURL)
} else {
return("")
}
}
add_Photo_URL <- function(in_csv){
#Input CSV data frame, appends photourl column
#Requires SKU (UPC) assumes no photourl column
out_csv <- mutate(in_csv, photo =
get_photo_url_from_product_info_output(
getProductInfo(SKU)
)
)
}
return (out_csv)
}
#Call it
new <- add_Photo_URL(old)
My thinking was that R would simply input the SKU of the from the row, and put it through the double function call "as is", and the vectorized DPLYR function mutate would just vectorize it. Unfortunately I was running into all sorts of problems I couldn't understand. Eventually I figured out that API call was crashing because the SKU field was all messed up as it was being passed in. I put in a breakpoint and found out that it wasn't just passing in the SKU, but instead an entire list (I think?) of SKUs. Every Row all at once. Something like this:
#Variable 'barcode' inside getProductInfo function contains:
[1] 7.869368e+11 1.438175e+10 1.256983e+10 2.454357e+10 3.139814e+10 1.256983e+10 1.313260e+10 4.339643e+10 2.454328e+10
[10] 1.313243e+10 6.839046e+11 2.454367e+10 2.454363e+10 2.454367e+10 2.454348e+10 8.418870e+11 2.519211e+10 2.454375e+10
[19] 2.454381e+10 2.454381e+10 2.454383e+10 2.454384e+10 7.869368e+11 2.454370e+10 2.454390e+10 1.913290e+11 2.454397e+10
[28] 2.454399e+10 2.519202e+10 2.519205e+10 7.742121e+11 8.839291e+11 8.539116e+10 2.519211e+10 2.519211e+10 2.519211e+10
Obviously my initial getProductInfo function can't handle that, so it'll crash.
How should I modify my code, whether it be in the input or API call to avoid this vectorized operation issue?
Well, it's not totally elegant but it works.
I figured out I need to use lapply, which is usually not my strong suit. Initally I tried to nest them like so:
lapply(SKU, get_photo_url_from_product_info_output(getProductInfo())
But that didn't work. So I just came up with bright idea of making another function
get_photo_url_from_sku <- function(barcode){
return(get_photo_url_from_product_info_output(getProductInfo(barcode)))
}
Call that in the lapply:
out_csv<- mutate(in_csv, photocolumn = lapply(SKU, get_photo_url_from_sku))
And it works great. My speed is only limited by my API calls.

Why does adding a return() in a for loop make a difference?

I'm playing around for loops in R, and have my data as x < -data.frame(rnorm(5))
Then I'm doing a for loop like this:
for (i in 1:nrow(x)){
x$new[i] <- x$rnorm.5.[i] + 1
return(x)
}
It returns
rnorm.5. new
0.4036397 1.40364
1.1424362 1.40364
0.2314323 1.40364
0.7248371 1.40364
0.6802016 1.40364
with all value in the new column the same.
However, if I remove the return(x), or change it into print(x), it instead gives me a different df:
rnorm.5. new
0.4036397 1.40364
1.1424362 1.1424362
0.2314323 1.2314323
0.7248371 1.7248371
0.6802016 1.6802016
Any idea would be appreciated!
When you write return(x), it ends the function, even if it's inside of a loop, so the loop stops here and doesn't loop anymore.
When you write print(x), it prints but the function and the loop keep going
Additionnal info provided by #Amar :
return will pass whatever value out of the function/loop for usage, while print simply prints to the console. For example, if you want the output of a function to be assigned for later usage, you'd use return

If inside of double loop

Inside of double loop I create subset of data for each combination of Tv stations with months which is done by loops. For example I have monthsnumbers 7,8,9 and stations A,B,C. It happens that for Month 9 there is no station C.
Then subset is empty and function throws and error of no possible aggregation.
So as you can see I tried to use if statement that if there are 0 rows don't continue with the code but go on to the next loop.
But I still get the same error fck. message
can you please navigate me ?
for (Mesic in monthnumbers){
for (Stanica in TVstations){
Client<-data[data$month ==Mesic & data$Channel_group1 ==Stanica & data$Brand == brand, ]
if (nrow(Client)!=0)
###some code
Client_AGG<-aggregate(formula= Client$BUYING_GRPs ~ Client$Brand,data= Client,FUN = sum)
###some code
}
}
}
Like Gregor commented, there is likely a better way of going about this.
But a quick patch might be to put the error check before the Client<- line because that's where it's looking for a channel that doesn't exist. Check if data$Channel_group1 == Stanica even exists before trying to get data from it.
Another option using for loops is to cycle through what you know is there with something like this:
subsetindex <- unique(data[ ,c('month','Channel_group1')])
for(i in 1:nrow(subsetindex)){
Client<-data[data$month ==subsetindex[i,'month'] & data$Channel_group1 ==subsetindex[i,'Channel_group1'] & data$Brand == brand, ]
#other code
}

Resources