I have a question how to make a IF
for (i in 1:12){
for (j in 1:12) {
if (i != j) {
var = x + b
}
else{ }
}}
"else" I need that when they are equal to continue with j + 1 example: if i = 4 and j = 4 then continue with j = 5 and continue counting until the end of j and continue the process of when i! = j
I think you don't understand what is going on in your code or you don't understand what for loops do. One "trick" you can do is to actually print what happens in your for loops so that you will have one idea of what is going on. You could also do this with a piece of paper.
As they already pointed you out, you don't need the else because the for already takes care of this.
for (i in 1:12){
print("-------------------------------")
valueI <- paste0("my i value is ",i)
print(valueI)
for (j in 1:12) {
valueJ <- paste0("my j value is ",j)
print(valueJ)
if (i != j) {
#var = x + b
diff <- paste0(i, " is different than ", j)
print(diff)
}
else{
}
}
}
This code is the same as yours and will generate a log that explains you what happens step from step, you could also use a debugger but seeing your struggles, better use this for now. What are you trying to calculate? I feel like you want to calculate the power of something...
Related
I am trying to define a function with a for loop and inside a conditional in R studio. Yesterday I was able with the help of another thread to devise this piece of code. The problem is that I want to sum the vector elements ma for any possible x, so that is inside the function l. This is a simpler case which I am trying to solve to adapt the original model. However, I do not know how to proceed.
ma<-rep(0,20)
l <- function(x, ma) {
for(i in seq_along(ma)) {
if(i %% 2 == 1) {
ma[i] <- i + x
} else {
ma[i] <- 0
}
}
return(ma)
}
My problem is that I would like to have the sum of i+x+0+i+x... for any possible x. I mean a function of the kind for any possible x.
Question:
Can someone explain to me how to implement such a function in R?
Thanks in advance!
I am going to update the original function:
Theta_alpha_s<-function(s,alpha,t,Basis){
for (i in seq_along(Basis)){
if(i%% 2==1) {Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*cos(2*pi*i*t)}
else{Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*sin(2*pi*i*t)}
}
return(Basis)
}
If you don't want to change the values in Basis, you can create a new vector in the function (here result) that you will return:
l = function(s,alpha,t,Basis){
is.odd = which(Basis %% 2 == 1)
not.odd = which(Basis %% 2 == 0)
result = rep(NA, length(Basis))
result[is.odd] = s*is.odd^{-alpha-0.5}*sqrt(2)*cos(2*pi*is.odd*t)
result[not.odd] = s*not.odd^{-alpha-0.5}*sqrt(2)*sin(2*pi*not.odd*t)
#return(result)
return(c(sum(result[is.odd]), sum(result[not.odd])))
}
I've wrote this nested loop so that, in the inner loop, the code runs through the first row; then, the outer one updates the loop so as to allow the inner one to run though the second row (and so on). The data comes from 'supergerador', a matrix. "rodadas" is the row size and "n" is the column size. "vec" is the vector of interest. Thank you in advance!
Edit: i, j were initially assigned i = 1, j = 2
for(e in 1:rodadas) {
for(f in 1:(n-1)) {
if(j >= 10) {
vec[f] = min(supergerador[i, j] - supergerador[i, j - 1], 1 - supergerador[i, j])
}
else {
vec[f] = func(i, j)
}
j = j + 1
}
i = i + 1
}
func is defined as
func = function(i, j) {
minf = min(supergerador[i, j] - supergerador[i, j - 1], supergerador[i, j + 1] - supergerador[i, j])
return(minf)
}
For reference, this is what the nested loop returns. You can tell that it only went through a single row.
> vec
[1] 0.127387378 0.068119707 0.043472981 0.043472981 0.027431603 0.027431603
[7] 0.015739046 0.008010766 0.008010766
I'm not quite sure what you are intending to do here, but here is a few suggestions and code edits:
Suggestions:
If you have a for loop, use the loop-index for your subsetting (as much as plausible) and avoid additional indexes where plausible.
This avoids code clutter and unforseen errors when indices should be reset but aren't.
Avoid double subsetting variables whenever possible. Eg if you have multiple calls to x[i, j], store this in a variable and then use this variable in your result.
Single line functions are fine, but should add readability to your code. Otherwise inlining your code is optimal from an efficiency perspective.
Incorporating these into your code I beliieve you are looking for
for(i in 1:rodadas) {
for(j in 2:n) {
x1 = supergerador[i, j]
x2 = supergerador[i, j - 1]
if(j >= 10) {
vec[f] = min(x1 - x2, 1 - x1)
}
else {
vec[f] = min(x1 - x2, supergerador[i, j + 1] - x1)
}
}
}
Here i am making the assumption that you wish to loop over columns for every row up to rodadas.
Once you get a bit more familiarized with R you should look into vectorization. With a bit more knowledge of your problem, we should be very easily able to vectorize your second for loop, removing your if statement and performing the calculation in 1 fast sweep. But until then this is a good place to start your programming experience and having a strong understanding of for-loops is vital in any language.
My problem is that after some iterations in R the readLines() function doesn't extract the information needed anymore. And I don't know where this problem comes from.
I would like to scrape some player statistics from www.whoscored.com and loop over these players --> https://www.whoscored.com/Players/i
for (i in 1:20){
sc_act <- readLines("https://www.whoscored.com/Players/101537", warn = FALSE)
if (i == 1){
sc <- sc_act
j <- 0
}
if (sc == sc_act){
j <- j + 1
}
}
On the first iterations the result comes out as expected, it reads the sourcecode of the mentioned url into sc_act.
But then (after about 10 iterations)the result looks like this:
"<html style=\"height:100%\"><head><META NAME=\"ROBOTS\" CONTENT=\"NOINDEX, NOFOLLOW\"><meta name=\"format-detection\" content=\"telephone=no\"><meta name=\"viewport\" content=\"initial-scale=1.0\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"><script type=\"text/javascript\" src=\"/_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3\"></script></head><body style=\"margin:0px;height:100%\"><iframe src=\"/_Incapsula_Resource?SWUDNSAI=28&xinfo=9-5358627-0%200NNN%20RT%281545484419406%2074%29%20q%280%20-1%20-1%20-1%29%20r%280%20-1%29%20B12%2811%2c55645%2c0%29%20U2&incident_id=287001440012879521-35322777428756745&edet=12&cinfo=0b000000\" frameborder=0 width=\"100%\" height=\"100%\" marginheight=\"0px\" marginwidth=\"0px\">Request unsuccessful. Incapsula incident ID: 287001440012879521-35322777428756745</iframe></body></html>"
You are calling too much times quickly the same url, I recommed you to read the book "Automated Data Collection with R". One simple way to fix your issue could be to waint some seconds between iterations.
for (i in 1:20){
sc_act <- readLines("https://www.whoscored.com/Players/101537", warn = FALSE)
if (i == 1){
sc <- sc_act
j <- 0
}
if (sc == sc_act){
j <- j + 1
}
time <- runif(n = 1, 3, 5)
Sys.sleep(time) # Wait between 3 and 5 seconds each iteration
}
Or maybe changing your user agent...
I need help figuring out how to improve a for loop. It doesn't necessarily needs to be apply, I just thought it was the best way after researching it on StackOverflow. I tried following the guides I found on StackOverflow, but I'm a newbie and believe I'm not getting a good grasp on the apply function.
This is a reconstruction of the snippet I'm trying to change:
for (j in 1:NROW(teste2) {
for (z in 1:NROW(teste2)) {
if(is.na(teste2$DATE[z]==Sys.Date()+j-1) | z==NROW(teste2)){
teste2$SALDO[z] <- 0
}else{
if(teste2$SALDO[z]!=0 & teste2$DATE[z]==Sys.Date()+j-1){
teste2$SALDO[z+1] <- teste2$PREVISAO_FINAL2[z] + teste2$SALDO[z+1]
}else{
teste2$SALDO[z] <- teste2$SALDO[z]
}
}
}
I tried doing the following:
for (j in 1:NROW(teste2) {
rows = 1:NROW(teste2)
saldo_fn <- function(z){
return(if(is.na(teste2$DATE[z]==Sys.Date()+j-1) | z==NROW(teste2)){
teste2$SALDO[z] <- 0
}else{
if(teste2$SALDO[z]!=0 & teste2$DATE[z]==Sys.Date()+j-1){
teste2$SALDO[z+1] <- teste2$PREVISAO_FINAL2[z] + teste2$SALDO[z+1]
}else{
teste2$SALDO[z] <- teste2$SALDO[z]
}
})
}
teste2$SALDO <- sapply(rows, saldo_fn)
}
But when I run sum(teste2$SALDO) it gives a different value.
What am I doing wrong? how do I fix it?
You cannot use apply-family function to optimize the algorithm. The reason is the line:
teste2$SALDO[z+1] <- teste2$PREVISAO_FINAL2[z] + teste2$SALDO[z+1]
You are recursively changing the value of next element based on the value of current one.
It is possible avoid for-loop in by using recursion, i.e. if you see something like x[i+1] = x[i+1] + x[i] you should use either for-loops or recursive functions (I prefer for-loops they are much easier and there is no problem with call stack overflow), if you see something like z[i] = F(x[i], y[i]), where F is some function, you can use apply-family functions.
I'm trying to write a function in R that takes two inputs as strings. If neither input is set, it asks for the inputs and then continues the function.
Input < - function(j,k){
if ((j==j)&&(k==k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j,k)
}else if ((j=="<string here>")&&(k=="<string here>")){
....
}
}
I think the better way to structure your approach would be this, using optional arguments and testing to see if they are non-null before proceeding, though admittedly your posted question is very vague:
Input < - function(j=NA, k=NA) {
if (is.na(j) | is.na(k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j, k)
} else if ((j == "<string here>") & (k == "<string here>")) {
....
}
}
Although I personally prefer the is.NA or is.NULL (as in #Forrest 's answer), this is an alternative with missing that might look simpler for someone starting now with R.
Input <- function(j, k) {
if (missing(j) | missing(k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j, k)
} else if ((j == "<string here>") & (k == "<string here>")) {
....
}
}
I think it's simplest perhaps to put the readline code as the argument. The force commands force evaluation of that code at that point in the function. I don't think they're necessary but depending what else the function does, you may want to make sure that it's asking for j and k first instead of later; otherwise the code will be evaluated when it first needs to know what j and k are.
Input <- function(j = readline(prompt="Enter Input 1: "),
k = readline(prompt="Enter Input 2: ")) {
force(j)
force(k)
if ((j=="<string here>") && (k=="<string here>")) {
....
}
}