In a R session, I source a simple r script whose content is:
x = c(1,2)
x
as
source('my.r')
I wonder why running it in the R session doesn't show any output?
(I find that I can use print() to show the value of x.)
Thanks.
It is the way source is configured. You can change it with the options echo and print.eval:
echo logical; if TRUE, each expression is printed after parsing,
before evaluation.
print.eval logical; if TRUE, the result of
eval(i) is printed for each expression i; defaults to the value of
echo.
So try source("my.r", print.eval=TRUE)
So far as I understand it, when you run source, you are starting a separate environment inside which source is executing, just like any other function. As such, x "prints" the value of x inside that environment, but the console is one environment "up" the chain.
Try, for example,
foo<-function(x) {
x
return(4)
}
EDIT: James has more directly answered the "how" part of your question.
Related
I've written a prime-generating function generatePrimes (full code here) that takes input bound::Int64 and returns a Vector{Int64} of all primes up to bound. After the function definition, I have the following code:
println("Generating primes...")
println("Last prime: ", generatePrimes(10^7)[end])
println("Primes generated.")
which prints, unexpectedly,
Generating primes...
9999991
Primes generated.
This output misses the "Last prime: " segment of the second print statement. The output does work as expected for smaller inputs; any input at least up to 10^6, but somehow fails for 10^7. I've tried several workarounds for this (e.g. assigning the returned value or converting it to a string before calling it in a print statement, combining the print statements, et cetera) and discovered some other weird behaviour: if the "Last prime", is removed from the second print statement, for input 10^7, the last prime doesn't print at all and all I get is a blank line between the first and third print statements. These issues are probably related, and I can't seem to find anything online about why some print statements wouldn't work in Julia.
Thanks so much for any clarification!
Edit: Per DNF's suggestion, following are some reductions to this issue:
Removing the first and last print statements doesn't change anything -- a blank line is always printed in the case I outlined and each of the cases below.
println(generatePrimes(10^7)[end]) # output: empty line
Calling the function and storing the last index in a variable before calling println doesn't change anything either; the cases below work exactly the same either way.
lastPrime::Int = generatePrimes(10^7)[end]
println(lastPrime) # output: empty line
If I call the function in whatever form immediately before a println, an empty line is printed regardless of what's inside the println.
lastPrime::Int = generatePrimes(10^7)[end]
println("This doesn't print") # output: empty line
println("This does print") # output: This does print
If I call the function (or print the pre-generated-and-stored function result) inside a println, anything before the function call (that's also inside the println) isn't printed. The 9999991 and anything else there may be after the function call is printed only if there is something else inside the println before the function call.
# Example 1
println(generatePrimes(10^7)[end]) # output: empty line
# Example 2
println("This first part doesn't print", generatePrimes(10^7)[end]) # output: 9999991
# Example 3
println("This first part doesn't print", generatePrimes(10^7)[end], " prints") # output: 9999991 prints
# Example 4
println(generatePrimes(10^7)[end], "prime doesn't print") # output: prime doesn't print
I could probably list twenty different variations of this same thing, but that probably wouldn't make things any clearer. In every single case version of this issue I've seen so far, the issue only manifests if there's that function call somewhere; println prints large integers just fine. That said, please let me know if anyone feels like they need more info. Thanks so much!
Most likely you are running this code from Atom Juno which recently has some issues with buffering standard output (already reported by others and I also sometimes have this problem).
One thing you can try to do is to flush your standard output
flush(stdout)
Like with any unstable bug restarting Atom Juno also seems to help.
I had the same issue. For me, changing the terminal renderer (File -> Settings -> Packages -> julia-client -> Terminal Options) from webgl to canvas (see pic below) seems to solve the issue.
change terminal renderer
I've also encountered this problem many times. (First time, it was triggered after using the debugger. It is probably unrelated but I have been using Julia+Juno for 2 weeks prior to this issue.)
In my case, the code before the println statement needed to have multiple dictionary assignation (with new keys) in order to trigger the behavior.
I also confirmed that the same code ran in Command Prompt (with same Julia interpreter) prints fine. Any hints about how to further investigate this will be appreciated.
I temporarily solve this issue by printing to stderr, thinking that this stream has more stringent flush mechanism: println(stderr, "hello!")
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.
If I want to know, whether variable v exists in zsh, I can use ${+v}. Example:
u=xxx
v=
print ${+u} ${+v} ${+w}
outputs 1 1 0.
If I want to access the content of a variable, where I have the NAME of it stored in variable v, I can do it with ${(P)v}. Example:
a=xxx
b=a
print ${(P)b}
outputs xxx.
Now I would like to combine the two: Testing whether a variable exists, but the name of the variable is stored in another variable. How can I do this? Example:
r=XXX
p=r
q=s
Here is my approach which does NOT work:
print ${+${(P)p}} # Expect 1, because $p is r and r exists.
print ${+${(P)q}} # Expect 0, because $q is s and s does not exist
However, I get the error message zsh: bad substitution.
Is there a way I can achieve my goal without reverting to eval?
print ${(P)+p}
print ${(P)+q}
The opening parenthesis of of a Parameter Expansion Flag needs to follow immediately after the opening brace. Also, it is not necessary to explicitly substitute p or q as (P) takes care of that. Nevertheless, ${(P)+${p}} and ${(P)+${q}} would also work.
I would like to run two commands, x and y, and define an environmentvariable V just for these too. Is there an easy way to do it in zsh? The "bash-like" solution, i.e.
(export V=myvalue; x; y)
is cumbersome and works only with a subshell, not a compound. However, the following two versions are syntactically invalid:
V=myvalue ( x ; y ) # No!
V=myvalue { x ; y } # No!No!No!
It is not possible without at least some extra code.
The modification of the environment by prepending variable assignments works only with Simple Commands. Meaning that the first word after the variable assignments needs to be the name of a simple (as in "not complex") command. Complex commands include { list } and ( list ) contstructs. (See the documentation on Complex Commands for a complete list)
If you want to modify the environment for a specific list of commands without changing the environment of your current shell, I can think of two ways to achive that
As mentioned in the question there is the rather straight-forward solution by runnig a subshell and exporting the variable explicitly:
(export V=myvalue; x; y)
You can use eval to avoid creating a subshell:
V=myvalue eval "x; y"
V=myvalue eval x\; y
This also saves three to four characters compared to the first solution. The main drawback seems to be that completion does not work very well inside the argument list for eval.
It's a little longer, but not much. You can define a function, then immediately call it as a simple command.
f () { x; y; }; V=foo f
Or, you could do a local export with an anonymous function:
() { local -x V=myvalue; x; y }
Suppose I have a small function in R
getsum <- function(a, b){
c <- a+b
}
Now when I run this function, It runs rormally. But my question is can I check the assigned value to c on console? I know that:
I can print its value within function, which will get reflected on console
I can return this value via return keyword.
I don't want any of these. My question is specifically, whether I can check the value of variables inside a function at console. I tried functionname::variablename, but it is not working
So there are a couple of answers I could give here, I'm not positive what you need it for.
(EDIT: oh, and FYI, I would avoid using "c" as a variable name, that's a function, the ambiguous value is bad. R will compensate by using the value in your current environment, but that's a stopgap measure)
The easiest would be to assign some variable:
x <- NULL
at the global environment level, and then, somewhere, during the function:
x <<- c
the double arrow assigns the value to the topmost environment.
However, this is a bit dangerous, as it's going to run as far up as it can to assign that variable. If you're after debugging, then I recommend adding:
browser()
inside the code somewhere, it will stop execution during the function and then you can run whatever you like inside the function environment.
If you want to debug your code, just use RSTUDIO https://www.rstudio.com/ is an IDE with debugging capabilities. In Rstudio setting a breakpoint inside your function and can check the value of internal variables in the right panels.