I am currently having a problem with R not following my break command.
Here are my two inputs:
Elements should not be bigger than 16, but it is returning two elements bigger than 16:
for (ndx in calc:length(b)) {
print(calc)
if(calc >16) {break}
For this one, I should not be getting elements in my loop that are >50 and <6, but am getting them anyways:
for(ndx in a){
print (a^2)
if (a>50 && a<6) {next}}
Could anyone tell me what I am doing wrong?
For the first one, replacing the variables with more generic names (I'm assuming that calc is an integer, otherwise the : operator shouldn't work anyway)
for (i in j:k) {
print(j)
if (j>16) break
}
Note that the value of j is not changing during the loop (the index variable i is never used in the loop, and no variables get modified in the loop, so nothing changes due to the loop body except for the index variable). So if j>16 it will be printed exactly once (provided length(j:k) is at least 1). Otherwise the loop will never break and j will be printed length(j:k) times.
Maybe
for (i in j:k) {
print(i)
if (i>16) break
}
is what you had in mind??
You do an unconditional print first, then you test the condition. Surely you should test the condition first, before printing?
Related
I have a problem of using a variable in R Studio. My code is as following. "child_birth" is a vector composed of 49703 strings that indicates some information about the birth of childre. What I did here is to tell whether the last 7 characters in each element of the vector is "at home". So I used a for loop and an if statement. if it is "at home", then the corresponding element in vector "GetValue" will be TRUE.
forloop <- (1:49703)
for (i in forloop){
temp <- child_birth[i]
if (substr(temp, nchar(temp)-6, nchar(temp)) == "at home" ) {
GetValue[i] = TRUE
}
else{ GetValue[i] = FALSE }
}
I googled it to make sure that in R I don't need to do a predecalration before using a variable. but when I ran the code above, I got the error information:" Error: object 'GetValue' not found". So what's the problem with it?
Thank you!
GetValue[i] only makes sense if GetValue (and i) exist. Compare: x+i only makes sense if x and i exist, which has nothing to do with whether or not x and i must be declared before being used.
In this case, you need to define GetValue before the loop. I recommend
GetValue <- logical(length(child_birth))
so as to allocate enough space. In this case, you could drop the else clause completely since the default logical value is FALSE.
I also recommend dropping the variable forloop and using
for(i in seq_along(child_birth))
Why hard-wire in the magic number 49703? Such numbers are subject to change. If you put them explicitly in the code, you are setting yourself up for future bugs.
So, I'm brushing up on how to work with data frames in R and I came across this little bit of code from https://cloud.r-project.org/web/packages/data.table/vignettes/datatable-intro.html:
input <- if (file.exists("flights14.csv")) {
"flights14.csv"
} else {
"https://raw.githubusercontent.com/Rdatatable/data.table/master/vignettes/flights14.csv"
}
Apparently, this assigns the strings (character vectors?) in the if and else statements to input based on the conditional. How is this working? It seems like magic. I am hoping to find somewhere in the official R documentation that explains this.
From other languages I would have just done:
if (file.exists("flights14.csv")) {
input <- "flights14.csv"
} else {
input <- "https://raw.githubusercontent.com/Rdatatable/data.table/master/vignettes/flights14.csv"
}
or in R there is ifelse which also seems designed to do exactly this, but somehow that first example also works. I can memorize that this works but I'm wondering if I'm missing the opportunity to understand the bigger picture about how R works.
From the documentation on the ?Control help page under "Value"
if returns the value of the expression evaluated, or NULL invisibly if none was (which may happen if there is no else).
So the if statement is kind of like a function that returns a value. The value that's returned is the result of either evaulating the if or the then block. When you have a block in R (code between {}), the brackets are also like a function that just return the value of the last expression evaluated in the block. And a string literal is a valid expression that returns itself
So these are the same
x <- "hello"
x <- {"hello"}
x <- {"dropped"; "hello"}
x <- if(TRUE) {"hello"}
x <- if(TRUE) {"dropped"; "hello"}
x <- if(TRUE) {"hello"} else {"dropped"}
And you only really need blocks {} with if/else statements when you have more than one expression to run or when spanning multiple lines. So you could also do
x <- if(TRUE) "hello" else "dropped"
x <- if(FALSE) "dropped" else "hello"
These all store "hello" in x
You are not really missing anything about the "big picture" in R. The R if function is atypical compared both to other languages as well as to R's typical behavior. Unlike most functions in R which do require assignment of their output to a "symbol", i.e a proper R name, if allows assignments that occur within its consequent or alternative code blocks to occur within the global environment. Most functions would return only the final evaluation, while anything else that occurred inside the function body would be garbage collected.
The other common atypical function is for. R for-loops only
retain these interior assignments and always return NULL. The R Language Definition calls these atypical R functions "control structures". See section 3.3. On my machine (and I suspect most Linux boxes) that document is installed at: http://127.0.0.1:10731/help/doc/manual/R-lang.html#Control-structures. If you are on another OS then there is probably a pulldown Help menu in your IDE that will have a pointer to it. Thew help document calls them "control flow constructs" and the help page is at ?Control. Note that it is necessary to quote these terms when you wnat to access that help page using one of those names since they are "reserved words". So you would need ?'if' rather than typing ?if. The other reserved words are described in the ?Reserved page.
?Control
?'if' ; ?'for'
?Reserved
# When you just type:
?if # and hit <return>
# you will see a "+"-sign which indicateds an incomplete expression.
# you nthen need to hit <escape> to get back to a regular R interaction.
In R, functions don't need explicit return. If not specified the last line of the function is automatically returned. Consider this example :
a <- 5
b <- 1
result <- if(a == 5) {
a <- a + 1
b <- b + 1
a
} else {b}
result
#[1] 6
The last line in if block was saved in result. Similarly, in your case the string values are "returned" implicitly.
Iam using R to run a large number using input from a delimited table which is compost of 40000 row and 4 col. iam trying to implement the t test ,p value , but i have error which is (the data are essentially constant) , i used the for loop and apply for both case i had same issue the code is:
NormData3= NormData1[1:40000,1:5]
for(i in 1:nrow(NormData3)) {
g1=NormData3[i,2:3]
g2=NormData3[i,4:5]
p[i]=t.test(g1,g2,var.equal=TRUE)$p.value
}
I don't know what is the problem ??
It's nice that the software recognizes situations in which a sensible
answer can't be computed. At that point, there are two possible actions:
(1) stop with an informative error, and (2) silently return NA.
If you are running this in a iterative loop, you want the second output. Here is the small function for that :
my.t.test.p.value <- function(...) {
obj<-try(t.test(...), silent=TRUE)
if (is(obj, "try-error")) return(NA) else return(obj$p.value)
}
Use this function instead of t.test in your code. This will not disturb your loop and allows it to continue.
I am running the following code:
disc<-for (i in 1:33) {
m=n[i]
xbar<-sum(data[i,],na.rm=TRUE)/m
Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
Sx
i=i+1}
Running it:
>disc
NULL
Why is it giving me NULL?
This is from the documentation for for, accessible via ?`for`:
‘for’, ‘while’ and ‘repeat’ return ‘NULL’ invisibly.
Perhaps you are looking for something along the following lines:
library(plyr)
disc <- llply(1:33, function(i) {
m=n[i]
xbar<-sum(data[i,],na.rm=TRUE)/m
Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
Sx
})
Other variants exists -- the ll in llply stands for "list in, list out". Perhaps your intended final result is a data frame or an array -- appropriate functions exist.
The code above is a plain transformation of your example. We might be able to do better by splitting data right away and forgetting the otherwise useless count variable i (untested, as you have provided no data):
disc <- daply(cbind(data, n=n), .(), function(data.i) {
m=data.i$n
xbar<-sum(data.i,na.rm=TRUE)/m
sqrt(sum((data.i-xbar)^2,na.rm=TRUE)/(m-1))
})
See also the plyr website for more information.
Related (if not a duplicate): R - How to turn a loop to a function in R
krlmlr's answer shows you how to fix your code, but to explain your original problem in more abstract terms: A for loop allows you to run the same piece of code multiple times, but it doesn't store the results of running that code for you- you have to do that yourself.
Your current code only really assigns a single value, Sx, for each run of the for loop. On the next run, a new value is put into the Sx variable, so you lose all the previous values. At the end, you'll just end up with whatever the value of Sx was on the last run through the loop.
To save the results of a for loop, you generally need to add them to a vector as you go through, e.g.
# Create the empty results vector outside the loop
results = numeric(0)
for (i in 1:10) {
current_result = 3 + i
results = c(results, current_result)
}
In R for can't return a value. The unique manner to return a value is within a function. So the solution here, is to wrap your loop within a function. For example:
getSx <- function(){
Sx <- 0
disc <- for (i in 1:33) {
m=n[i]
xbar <- sum(data[i,],na.rm=TRUE)/m
Sx <- sqrt(sum((data[i,]-xbar)^2,na.rm=TRUE)/(m-1))
}
Sx
}
Then you call it:
getSx()
Of course you can avoid the side effect of using a for by lapply or by giving a vectorized But this is another problem: You should maybe give a reproducible example and explain a little bit what do you try to compute.
For the following code: I can't figure out why j does not print on every outside loop iteration.
x = 0
for (j in 1:15)
{
for (i in 1:100000)
{
x = x + 1
}
print(j)
}
What R seems to be doing is running the the whole thing, and at the end print out all the js, not one by one as when every loop iterates.
It seems to be that j should be printing after every loop iteration, what am I missing here?
Is there a way to make it such that j in printed on every outside loop iteration?
Thank You
I'm guessing you are using the Windows Rgui, which buffers its console output, and then writes it out in chunks (see the R Windows FAQ 7.1). To force immediate printing to the console, you can simply add a call to flush.console() after the print() statement.
x = 0
for (j in 1:15) {
for (i in 1:100000) {
x = x + 1
}
print(j)
flush.console()
}
R output is typically buffered. You can circumvent this in two ways. Either (only on Windows, IIRC) you can go to the menu of the R Gui, and chose Misc -> Buffered Output (or press Ctrl-W) to disable buffering (which typically slows down execution), or you can call flush.console() any time you want to ensure that the output is actually shown (e.g. to show progress).
Not familiar with R but that code looks right for what you are trying to do. May be something to do with output buffering as I've come accross the same issue in PHP where the whole script runs before any output is rendered.