Run cmd command from within R - r

I want to trigger/run a certain cmd command from within R. I found the functions system, system2 and shell, but am a bit lost on how to exactly use them.
So if I would do it directly in Windows, I'd open the cmd and then run the following command:
"C:\Program Files\LatentGOLD6.0\lg60" "C:\Users\USER\myfile.lgs" /b /o "C:\Users\USER\myfile.html" /h
However, I struggle with how and where I'd specify such a command in R so that it runs the thing. All of the mentioend functions above require a character string, but since I need to pass the paths with quotes, I'm actually not sure how I can glue all of this together.
Any ideas?
So here's my current code:
program_path <- "C:\Program Files\LatentGOLD6.0\lg60"
lgs_path <- "C:\Users\USER\myfile.lgs"
out_path <- "C:\Users\USER\myfile.html"
batchline <- paste0(program_path, " ", lgs_path, " /b /o ", out_path, " /h")
system(batchline)
system2(batchline)
Alternative also doesn't work: batchline <- paste0("'", program_path, "'", " ", "'", lgs_path, "'", " /b /o ", "'", out_path, "'", " /h")

Use r"{...}" if there are backslashes within the literal string as we do here or else double each backslash (see ?Quotes) or in some cases using forward slash in place of backslash will work. Then use sprintf to generate batchline.
program_path <- r"{C:\Program Files\LatentGOLD6.0\lg60}"
lgs_path <- r"{C:\Users\USER\myfile.lgs}"
out_path <- r"{C:\Users\USER\myfile.html}"
batchline <- sprintf("%s %s /b /o %s /h", program_path, lgs_path, out_path)
or if you want to surround each path with quotes then replace last line with:
batchline <- sprintf('"%s" "%s" /b /o "%s" /h', program_path, lgs_path, out_path)

EDIT: updated bug where I initially used forward slashes.
ok, found a solution with the help of this here: Adding double quotes to string in R, i.e. wrapping the file paths into shQuote works.
program_path <- normalizePath("C:/Program Files/LatentGOLD6.0/lg60")
lgs_path <- normalizePath("C:/Users/USER/myfile.lgs")
out_path <- normalizePath("C:/Users/USER/myfile.html")
batchline <- paste0(shQuote(program_path),
" ",
shQuote(lgs_path),
" /b /o ",
shQuote(out_path),
" /h")
system(batchline)

Related

How do I replace "/" with "\" in r?

I am trying do that "C:/Users/Vitor/Documents" become "C:\Users\Vitor\Documents".
I tried :
gsub("//", "\", file)
paste(dirname(file),basename(file),sep="\")
normalizePath(file,"\",mustWork=FALSE)
But didn't work!
We can escape the \ with another set and use it in gsub as the \\ is just one character
gsub("/", "\\\\", "C:/Users/Vitor/Documents")
which would print correctly with cat
cat(gsub("/", "\\\\", "C:/Users/Vitor/Documents"))
#C:\Users\Vitor\Documents
and can check the number of characters
nchar("\\")
#[1] 1

Replacing a special character does not work with gsub

I have a table with many strings that contain some weird characters that I'd like to replace with the "original" ones. Ä became ä, ö became ö, so I replace each ö with an ö in the text. It works, however, ß became à < U+009F> and I am unable to replace it...
# Works just fine:
gsub('ö', 'REPLACED', "Testing string ö")
# this does not work
gsub("Ã<U+009F>", "REPLACED", "Testing string Ã<U+009F> ")
# this does not work as well...
gsub("â<U+0080><U+0093>", "REPLACED", "Testing string â<U+0080><U+0093> ")
How do I tell R to replace These parts with some letter I want to insert?
As there are metacharacters (+ - to signify one or more), in order to evaluate it literally either escape (as #boski mentioned in the solution) or use fixed = TRUE
sub("Ã<U+009F>", "REPLACED", "Testing string Ã<U+009F> ", fixed = TRUE)
#[1] "Testing string REPLACED "
You have to escape the + symbol, as it is a regex command.
> gsub("Ã<U\\+009F>", "REPLACED", "Testing string Ã<U+009F> ")
[1] "Testing string REPLACED "
> gsub("â<U\\+0080><U\\+0093>", "REPLACED", "Testing string â<U+0080><U+0093> ")
[1] "Testing string REPLACED "

having R print a system call that contains "", '', and escape character \

I need to run a perl command from within an R script. I would normally do this via:
system(paste0('my command'))
However, the command I want to paste contains both single and double quotes and an escape character. Specifically, I would like to paste this command:
perl -pe '/^>/ ? print "\n" : chomp' in.fasta | tail -n +2 > out.fasta
I have tried escaping the double quotes with more escape characters, which allows me to pass the command, but it then prints all 3 escape characters, which causes the command to fail. Is there a good way around this, such that I can save the above perl line as a string in R, that I can then pass to the system() function?
Hey I haven't tested your particular perl call (since it involves particular file/directory etc) but tried something trivial by escaping the quotes and it seems to work. You might want to refer this question for more as well.
My approach,
# shouldnt have any text expect for an empty string
my_text <- try(system(" perl -e 'print \"\n\"' ", intern = TRUE))
my_text
[1] ""
# should contain the string - Hello perl from R!
my_text2 <- try(system(" perl -e 'print \"Hello perl from R!\"' ", intern = TRUE))
my_text2
[1] "Hello perl from R!"
So based on the above trials I think this should work for you -
try(system(command = "perl -pe '/^>/ ? print \"\n\" : chomp' in.fasta | tail -n +2 > out.fasta", intern = TRUE))
Note - intern = TRUE just captures the output as a character vector in R.

How to run a VBS script from R, while passing arguments from R to VBS

Let's say I want to run a VBS script from R, and I want to pass a value from R to that script.
For example, in a simple file called 'Msg_Script.vbs', I have the code:
Dim Msg_Text
Msg_Text = "[Insert Text Here]"
MsgBox("Hello " & Msg_Text)
How do I run this script using R, while editing the parameters and/or variables in R? In the above script for instance, how would I edit the value of the Msg_Text variable?
Another way would be to pass the value as an argument to the VBScript
You'd write the VBS as follows:
Dim Msg_Text
Msg_Text = WScript.Arguments(0)
MsgBox("Hello " & Msg_Text)
And then you'd create a system command in R like this:
system_command <- paste("WScript",
'"Msg_Script.vbs"',
'"World"',
sep = " ")
system(command = system_command,
wait = TRUE)
This approach matches the arguments by position.
If you wanted, you could use named arguments instead. This way, your VBS would look like this:
Dim Msg_Text
Msg_Text = WScript.Arguments.Named.Item("Msg_Text")
MsgBox("Hello " & Msg_Text)
And then you'd create a system command in R like this:
system_command <- paste("WScript",
'"Msg_Script.vbs"',
'/Msg_Text:"World"',
sep = " ")
system(command = system_command,
wait = TRUE)
Here's a somewhat-hackish solution:
Read the lines from the vbs script into R (using readLines()):
vbs_lines <- readLines(con = "Msg_Script.vbs")
Edit the lines in R by finding and replacing specific text:
updated_vbs_lines <- gsub(x = vbs_lines,
pattern = "[Insert Text Here]",
replacement = "World",
fixed = TRUE)
Create a new VBS script using the updated lines:
writeLines(text = updated_vbs_lines,
con = "Temporary VBS Script.vbs")
Run the script using a system command:
full_temp_script_path <- normalizePath("Temporary VBS Script.vbs")
system_command <- paste0("WScript ", '"', full_temp_script_path, '"')
system(command = system_command,
wait = TRUE)
Delete the new script after you've run it:
file.remove("Temporary VBS Script.vbs")

find the number of lines in a file

Under Linux, I can find the number of lines in a file by doing a system call to wc:
CountLines <- function(file) {
count.file <- system(sprintf("wc -l %s", file), intern = TRUE)
count <- as.integer(strsplit(count.file, " ")[[1]][1])
return(count)
}
How can I do this efficiently under Windows? By "efficient" I mean fast and light on resources, as I may be using it on large files.
As much as possible, I'd prefer a solution that does not require installing extra packages or tools.
Take a look at this link:
https://isc.sans.edu/diary/Finding+Files+and+Counting+Lines+at+the+Windows+Command+Prompt/2244
The last line works for me:
c:\> type c:\windows\win.ini | find /c /v "~~~"
# 32
Update:
if you want to use it as R function, try this:
CountLines <- function(file) {
stopifnot(file.exists(file))
unlikely.pattern <- paste(sample(LETTERS), collapse = "")
cmd <- sprintf('type %s | find /c /v "%s"', file, unlikely.pattern)
res <- shell(cmd, intern = TRUE)
return(as.integer(res))
}
CountLines("c:\\windows\\win.ini")
[1] 32
.
.
.
I found another way to do this more efficient, but I leave this to you for perfection:
> system("POWERSHELL Get-Content c:\\windows\\win.ini | Measure-Object -word -line -character", intern=TRUE)
[1] ""
[2] " Lines Words Characters Property "
[3] " ----- ----- ---------- -------- "
[4] " 32 38 414 "
[5] ""
[6] ""

Resources