passing variable in r system command - r

I am trying to pass variable as an argument to system command in R.
> system("ls>abc.csv") #this works
> k<-"abc.csv"
> system("ls>k") #this does not work
> system2("ls>k") #this does not work
sh: ls>k: command not found
> system("ls>$k") #this does not work
sh: $k: ambiguous redirect

You can use paste to build the OS command and pass to system
system(paste("ls >", k))

The problem here is that R does not recognize variable k if you put it in a string.
But indeed it is very useful to put the file name in a variable if you want to use it again and again.
Can you try
system(paste0("ls>", k))
If this works, you can also write a small function:
"%&%" <- function(a, b)paste0(a, b)
And then you can do
system("ls>"%&%k)

Related

R readLines from console- how to signal end of input

I want to use readLines function for input from console of variable number of lines and store it to a vector:
v <- readLines()
How do I signal the end of input? Control-c cancels the process and no 'v' object is formed. Control-Z stops R program altogether. Typing 'EOL' or 'EOF' do not work.
I tried following function but it gives error:
getinput = function(){
v=""
while(TRUE){
line = readLines(n=1)
if(line=="") break
v = v+line
}
v
}
> getinput()
firstentry
Error in v + line : non-numeric argument to binary operator
>
I am using R on Debian Linux. Thanks for your help.
<CTRL-D> will signal EOF. If you're using ess, try C-c C-c. Hope that helps and good luck. Leave a comment if you need further assistance.

Pass file name to perl from R

I want to pass file name to perl from R. For example, this system command from R to execute perl works well
system("perl file.pl name.txt")
name.txt is already existing in the R working directory. Now,
a<-"name.txt"
how to pass this to perl?
If I understand correctly I think this may work:
a <- "name.txt"
system(sprintf("perl file.pl %s", a))
Tyler's method works, but there is also this way:
a <- "name.txt"
system(paste("perl file.pl", a))
Depending on the situation, one may be more intuitive over the other.

Debugging unexpected errors in R -- how can I find where the error occurred?

Sometimes R throws me errors such as
Error in if (ncol(x) != 2) { : argument is of length zero
with no additional information, when I've written no such code. Is there a general way for finding which function in which package causes an error?
Since most packages come compressed, it isn't trivial to grep /usr/lib/R/library.
You can use traceback() to locate where the last error occurred. Usually it will point you to a call you make in your function. Then I typically put browser() at that point, run the function again and see what is going wrong.
For example, here are two functions:
f2 <- function(x)
{
if (x==1) "foo"
}
f <- function(x)
{
f2(x)
}
Note that f2() assumes an argument of length 1. We can misuse f:
> f(NULL)
Error in if (x == 1) "foo" : argument is of length zero
Now we can use traceback() to locate what went wrong:
> traceback()
2: f2(x) at #3
1: f(NULL)
The number means how deep we are in the nested functions. So we see that f calls f2 and that gives an error at line 3. Pretty clear. We could reassign f with browser placed just before the f2 call now to check it's input. browser() simply allows you to stop executing a function and look around in its environment. Similar to debug and debugonce except that you don't have to execute every line up until the point you know something goes wrong.
Just to add to what #SachaEpskamp has already suggested, setting options(error=recover) and options(show.error.locations=TRUE) can be extremely helpful when debugging unfamiliar code. The first causes R to launch a debugging session on error, giving you the option to invoke the browser at any point in the call stack up to that error. The second option will tell R to include the source line number in the error.

octave map over multiple arguments

I want to map a function that takes two arguments over two vectors of the same length, taking an argument from each of these vectors. I can do it with one argument:
map(#sqrt, 1:10)
ans = ....
help map gives the following example:
map(#min, A, B)
ans = ...
where A and B are 2 by 2 matrices, and the result matrix is the element-wise minimum. But when I try this example, I get the following error:
A = rand(2,2);
B = rand(2,2);
map(#min, A, B)
error: invalid assignment to cs-list outside multiple assignment.
error: assignment to cell array failed
error: assignment failed, or no method for `<unknown type> = scalar'
error: called from:
error: C:\Octave\3.2.4_gcc-4.4.0\share\octave\packages\miscellaneous-1.0.9\map.m at line 108, column 21
What am I doing wrong? My system is Win7, 64 bit, and as you can see, my octave version is 3.2.4.
Thanks to this question, I was able to find out that map is being deprecated, and the correct function to use is arrayfun, which works out of the box, both with octave version 3.2.4, which is what I got when downloading a normal windows installer, and with octave version 3.6.2, which I got using cygwin. In version 3.6.2 it even seems that map requires the miscellaneous package, which arrayfun does not.
So I will never know what I did wrong, or if there is a bug (unlikely, given that the function is pretty standard), but my problem was solved by just substituting arrayfun:
A = rand(2,2);
B = rand(2,2);
arrayfun(#min, A, B)
ans = .... % correct answer

Can't add constant to vector in R

I don't know what is happening, but I can't seem to add a constant to a vector. For example, typing in the console c(1,2,3,4)+5 returns 15 instead of (6,7,8,9). What am I doing wrong?
Thank you for your help.
Someone.... probably you ... has redefined the "+" function. It's easy to do:
> `+` <- function(x,y) sum(x,y)
> c(1,2,3,4)+5
[1] 15
It's easy to fix, Just use rm():
> rm(`+`)
> c(1,2,3,4)+5
[1] 6 7 8 9
EDIT: The comments (which raised the alternate possibility that c had instead been redefined as sum) are prompting me to add information about how to examine and recover from the alternative possibilities. You could use two methods to determine which of the two functions in the expression c(1,2,3,4) + 5 was the culprit. One could either type their names (with the backticks enclosing +), and note whether you got the proper definition:
> `+`
function (e1, e2) .Primitive("+")
> c
function (..., recursive = FALSE) .Primitive("c")
Using rm on the culprit (the on that doesn't match above) remains the quickest solution. Using a global rm is an in-session brainwipe:
rm(list=ls())
# all user defined objects, including user-defined functions will be removed
The advice to quit and restart would not work in some situations. If you quit-with-save, the current function definitions would be preserved. If you had earlier quit-with-save from a session where the redefinition occurred, then not saving in this session would not have fixed the problem, either. The results of prior session are held in a file named ".Rdata and this file is invisible for both Mac and Windows users because the OS file viewer (Mac's Finder.app or MS's Windows Explorer) will not display file names that begin with a "dot". I suspect that Linux users get to see them by default since using ls in a Terminal session will show them. (It's easy to find ways to change that behavior in a Mac, and that is the way I run my device.) Deleting the .Rdata file is helpful in this instance, as well as in the situation where your R session crashes on startup.

Resources