What is a neat command line equivalent to RStudio's Knit HTML? - r

What is a neat command line equivalent to RStudio's Knit HTML? Given an .Rmd file, you can use RStudio to knit .html, .docx and .pdf files using Knitr. It would be great to shift this process completely to the command line. My approach so far:
Rscript -e "library(knitr); knit('test.Rmd')" # This creates test.md
pandoc test.md >> test.html
This works fine, but the resulting test.html does not come with the same pretty make over as in RStudio. Any suggestions how one should best knit .Rmd files to .html via the command line, and end up with a pretty .html?
Extra question: What would be the best command line solution for .pdf or .docx?

rmarkdown::render("test.Rmd", "html_document")

Following up on the accepted answer, I've drafted a bash script called "knitter" that will do everything needed, all the user needs to do is input: ./knitter file.Rmd file.html or ./knitter file.Rmd file.pdf.
The script is below:
#!/bin/sh
### Test usage; if incorrect, output correct usage and exit
if [ "$#" -gt 2 -o "$#" -lt 2 ]; then
echo "********************************************************************"
echo "* Knitter version 1.0 *"
echo "********************************************************************"
echo -e "The 'knitter' script converts Rmd files into HTML or PDFs. \n"
echo -e "usage: knitter file.Rmd file.{pdf,html} \n"
echo -e "Spaces in the filename or directory name may cause failure. \n"
exit
fi
# Stem and extension of file
extension1=`echo $1 | cut -f2 -d.`
extension2=`echo $2 | cut -f2 -d.`
### Test if file exist
if [[ ! -r $1 ]]; then
echo -e "\n File does not exist, or option mispecified \n"
exit
fi
### Test file extension
if [[ $extension1 != Rmd ]]; then
echo -e "\n Invalid input file, must be a Rmd-file \n"
exit
fi
# Create temporary script
# Use user-defined 'TMPDIR' if possible; else, use /tmp
if [[ -n $TMPDIR ]]; then
pathy=$TMPDIR
else
pathy=/tmp
fi
# Tempfile for the script
tempscript=`mktemp $pathy/tempscript.XXXXXX` || exit 1
if [[ $extension2 == "pdf" ]]; then
echo "library(rmarkdown); rmarkdown::render('"${1}"', 'pdf_document')" >> $tempscript
Rscript $tempscript
fi
if [[ $extension2 == "html" ]]; then
echo "library(rmarkdown); rmarkdown::render('"${1}"', 'html_document')" >> $tempscript
Rscript $tempscript
fi

My simpler command-line script, similar to Tyler R.'s:
In your .profile or similar, add:
function knit() {
R -e "rmarkdown::render('$1')"
}
Then, on command line, type knit file.Rmd
EDIT: For nice autocomplete, see comments
I set up output format in the Rmd header: output: github_document or similar

getwd()
setwd("C:Location of the RMD File")
# To make it in to PDF you can use the below code also
rmarkdown::render("Filname.Rmd")
# To make it in to PDF you can use the below code also
rmarkdown::render("Filename", "pdf_document")
I Typed the above in to a R Script and triggered it from Python command prompt and solved my requirement:)
Kindly note : if it doesn't work.. Try to install latex and try again.. All the best :)

From the mac/linux terminal, you could run:
R -e "rmarkdown::render('README.Rmd')"
(replacing README.Rmd with whatever file you wish to knit)

Related

zsh/bash source command behavior difference

I am trying to source a third party script in zsh (named setup_env.sh stored in ~/), that has following lines in the beginning to guard against accidental execution:
#!/bin/sh
# Guard the script against execution - it must be sourced!
echo $0 | egrep 'setup_env.sh' > /dev/null
if [ $? -eq 0 ]; then
echo ""
echo "ERROR: the setup file must be SOURCED, NOT EXECUTED in a shell."
echo "Try (for bash) : source setup_env.sh"
echo "Or (eg. for ksh): . setup_env.sh"
exit 1
fi
# export some environment variables
...
When I source this script with source ~/setup_env.sh, I see the error message shown in the above code block.
From the script it's apparently visible that it's not written with zsh in mind. But I still want to know why zsh behaves this way, and if it's possible to source the script as it is.
I could source the script as it is without error using bash.
I could also source it in zsh after commenting out the guard block in the beginning of the script.
Can someone explain this difference in behavior for source command between zsh and bash?
zsh/bash have different ways to detect sourcing, following should work for both :
if [[ -n $ZSH_VERSION && $ZSH_EVAL_CONTEXT == toplevel ]] || \
[[ -n $BASH_VERSION && $BASH_SOURCE == $0 ]]; then
echo "Not sourced"
exit 1
fi
To explain a little more, when you run :
source setup_env.sh
# setup_env.sh containing "echo $0"
In zsh, $0 == setup_env.sh
In bash, $0 == bash

How to give output location of file in shell script?

I have a a Shell script that contain a Perl script and R script.
my Shell script R.sh:-
#!/bin/bash
./R.pl #calling Perl script
`perl -lane 'print $F[0]' /media/data/abc.cnv > /media/data/abc1.txt`;
#Shell script
Rscript R.r #calling R script
This is my R.pl (head):-
`export path=$PATH:/media/exe_folder/bin`;
print "Enter the path to your input file:";
$base_dir ="/media/exe_folder";
chomp($CEL_dir = <STDIN>);
opendir (DIR, "$CEL_dir") or die "Couldn't open directory $CEL_dir";
$cel_files = "$CEL_dir"."/cel_files.txt";
open(CEL,">$cel_files")|| die "cannot open $file to write";
print CEL "cel_files\n";
for ( grep { /^[\w\d]/ } readdir DIR ){
print CEL "$CEL_dir"."/$_\n";
}close (CEL);
The output of Perl script is input for Shell script and Shell's output is input for R script.
I want to run the Shell script by providing the input file name and output file name like :-
./R.sh home/folder/inputfile.txt home/folder2/output.txt
If folder contain many files then it will take only user define file and process it.
Is There is a way to do this?
I guess this is what you want:
#!/bin/bash
# command line parameters
_input_file=$1
_output_file=$2
# #TODO: not sure if this path is the one you intended...
_script_path=$(dirname $0)
# sanity checks
if [[ -z "${_input_file}" ]] ||
[[ -z "${_output_file}" ]]; then
echo 1>&2 "usage: $0 <input file> <output file>"
exit 1
fi
if [[ ! -r "${_input_file}" ]]; then
echo 1>&2 "ERROR: can't find input file '${input_file}'!"
exit 1
fi
# process input file
# 1. with Perl script (writes to STDOUT)
# 2. post-process with Perl filter
# 3. run R script (reads from STDIN, writes to STDOUT)
perl ${_script_path}/R.pl <"${_input_file}" | \
perl -lane 'print $F[0]' | \
Rscript ${_script_path}/R.r >"${_output_file}"
exit 0
Please see the notes how the called scripts should behave.
NOTE: I don't quite understand why you need to post-process the output of the Perl script with Perl filter. Why not integrate it directly into the Perl script itself?
BONUS CODE: this is how you would write the main loop in R.pl to act as proper filter, i.e. reading lines from STDIN and writing the result to STDOUT. You can use the same approach also in other languages, e.g. R.
#!/usr/bin/perl
use strict;
use warnings;
# read lines from STDIN
while (<STDIN>) {
chomp;
# add your processing code here that does something with $_, i.e. the line
# EXAMPLE: upper case first letter in all words on the line
s/\b([[:lower:]])/\U\1/;
# write result to STDOUT
print "$_\n";
}

unix: Can I delete files in a directory that do not contain text?

Can I delete files in a directory that do NOT contain any text? These are text files with the extension '.fasta'. Initially I am running this script:
for g in `cat genenames.txt` ; do cat *${g}_*.fa > $g.fasta ; done
On a list of files that look like:
id_genename_othername.fa
But in some directories, not all the genenames from the list (genenames.txt) have files with names that match. So sometimes I will get this message:
cat: *genename_*.fa: No such file or directory
The above code still makes a '.fasta' file with the genename that doesn't exist and I would like to remove it. THANK YOU.
Assuming your script is using #!/bin/bash, I'd do
shopt -s nullglob
while IFS= read -r pattern; do
files=( *"$pattern"*.fa )
if [[ "${#files[#]}" -eq 0 ]]; then
echo "no files match pattern *$pattern*.fa"
else
cat "${files[#]}" > $pattern.fasta
fi
done < genenames.txt
Have you tried the following?
for g in `cat genenames.txt` ; do cat *${g}_*.fa 2>/dev/null > $g.fasta ; done
This should prevent the not found errors from producing files

convert the CR/LF line terminators in that file to Unix-style LF line terminators?

Please help. I need to turn this in before 4pm for this Unix class. I have been working on it since 7pm last night. Haven't slept. There are three parts to this assignment. I only need help with the last part. If I can't complete this I fail the class.
Stage 3
In that same directory, write a script asciiFix.sh that takes an arbitrary number of file paths from the command line and carries out the same analysis on each one. If a file is not Windows ASCII, your script should do nothing to it. For each file that is Windows ASCII, your script should print the message
converting fileName
and should then convert the CR/LF line terminators in that file to Unix-style LF line terminators.
For example:
cp ~cs252/Assignments/ftpAsst/d3.dat wintest.txt
./asciiFix.sh /usr/share/dict/words wintest.txt fileType.sh
converting wintest.txt
and, after the script has finished, you should be able to determine that wintest.txt is now a Unix ASCII file.
When you believe that you have your script working, run
~cs252/bin/scriptAsst.pl
If all three scripts are working correctly, you will receive your access code.
My Attemps:
#!/bin/sh
for file in "$#" do
if file "$file" | grep "ASCII text, with CRLF"; then
echo "converting $file"
sed -e s/[\\r\\n]//g "$file"
fi
done
result:
./asciiFix.sh: 3: ./asciiFix.sh: Syntax error: "if" unexpected (expecting "do")
aardvark.cpp /home/cs252/Assignments/scriptAsst/winscrubbed.dat differ: byte 50, line 1
Failed: incorrect file conversion when running ./asciiFix.sh 'aardvark.cpp' 'bongo.dat' ' cat.dog.bak
Ii have tried taking out if and then. i have tried sed -i 's/^M//g' "$file",also using dos2unix, as well as some other stuff I dont remember. but it always says incorrect conversion with those files.
After adding the ; and switching to dos2unix:
#!/bin/sh
for file in "$#";
do
if file "$file" | grep "ASCII text, with CRLF"; then
echo "converting $file"
dos2unix "$file"
fi
done
the Error that I now get:
dos2unix: converting file aardvark.cpp to Unix format ...
Failed when running: ./asciiFix.sh 'aardvark.cpp' 'bongo.dat' 'cat.dog.bak'
Thanks for all your help.
The code that finally worked was:
#!/bin/sh
for file in "$#";
do
if file "$file" | grep -q "ASCII text, with CRLF"; then
echo "converting $file"
dos2unix "$file"
fi
done
You forgot the ; before do. do counts as a new statement. Alternatively you could place the do on a new line. In my opinion, the most comfortable way to convert DOS line endings (CRLF) to Unix line endings (LF-only) is dos2unix. If you fix your ;error, using dos2unix instead of sed should be straight forward and trivial.
Since dos2unix 7.1 you can use dos2unix itself to test for CRLF. This way you are not limited to ASCII.
#!/bin/sh
for file in "$#";
do
if [ -n "$(dos2unix -ic $file)" ]; then
echo "converting $file"
dos2unix "$file"
fi
done

unable to run awk command as a shell script

i am trying to create a shell script to search for a specific index in a multiline csv file.
the code i am trying is:
#!/bin/sh
echo "please enter the line no. to search: "
read line
echo "please enter the index to search at: "
read index
awk -F, 'NR=="$line"{print "$index"}' "$1"
the awk command I try to use on the shell works absolutely fine. But when I am trying to create a shell script out of this command, it fails and gives no output. It reads the line no. and index. and then no output at all.
is there something I am doing wrong?
I run the file at the shell by typing:
./fetchvalue.sh newfile.csv
Your quoting is not going to work. Try this:
awk -F, 'NR=="'$line'"{print $'$index'}' "$1"
Rather than going through quoting hell, try this:
awk -F, -v line=$line -v myindex=$index 'NR==line {print $myindex}' "$1"
(Index is a reserved word in awk, so I gave it a slightly differet name)

Resources