R
is very C
like in it's syntaxif (condition) {
} else {
}
else if (condition) {
}
## This won't work, else needs to be on same line as end of if
if( 4 > 5) {
print("Bad Math")
}
else {
print("Seems right to me")
}
if( 4 > 5) {
print("Bad Math")
} else {
print("Seems right to me")
}
a <- 4
b <- 2
if ( a %% b == 0)
{
print(paste(a,"is even"))
} else {
print(paste(a,"is odd"))
}
## Produces warning only, probably not the intended test condition
vec1 <- c(2,4,6,8)
if( vec1 %% 2 == 0){
print("All elements are even")
} else{
print("Not all elements are even")
}
vec1 <- c(2,4,6,8)
if( all(vec1 %% 2 == 0)){
print("All elements are even")
} else{
print("Not all elements are even")
}
if
on the right hand side of an assignmentvar <- if (condition){
value
}
else{
value
}
ifelse
function to apply to vectorsifelse(expression_generating_boolean_vector, value_if_true, value_if_false)
num1 <- 100
num2 <- 1000
largest_num <- if(num1 > num2){
num1
} else {
num2
}
print(largest_num)
float <- 100.004
truncated <- if (float %% 1 != 0){
float %/% 1
} else{
float
}
print(truncated)
vec3 <- 1:10
print(ifelse(vec3 %% 3 == 0,
"Is Divisible by 3",
"Isn't Divisibly by 3" ))
vec4 <- -5:5
print(ifelse(vec4 < 0,-1,1))
R
doesn't have a switch statement, only a switch
functionswitch(expression, value1, value2, value3...)
switch(expression, key1 = value1, key2 = value2, default)
word <- switch(3,"one","two","three","four","five","six","seven")
print(word)
translation <- switch(word, one="uno",two="dos",
three="tres",four="quatro",
"un numero")
print(translation)
print(switch("seven", one="uno",two="dos",
three="tres",four="quatro",
"un numero"))
R
look like for-each loops, but are still numericseq_along(X)
produces the sequence of indices for a given object to loop throughfor(var in integer_vector){
}
for(i in 1:5){
print(i ^ 2)
}
print(mtcars)
## How can I make this print thet names of the column?
for (feature in seq_along(mtcars)){
print(paste("The median is",
median(mtcars[[feature]])))
}
R
offers only one truly controlled logic loop, the standard while
loopwhile(condition){
}
R
also provides a repeat loop, which repeats forever, and must be broken out of explicitlyrepeat{
if(condition) break
}
haystack <- c(1,34,5,5,1,4,6,0)
i <- 1
while(haystack[i] != 6){
i <- i + 1
}
print(paste("I found 6 at position",i))
end <- 1
repeat{
print("This is the song that never ends, yes it goes on and on my friends,
some people started singing it not knowing what it was, and they will keep on
singing it forever just because...")
if (end == 10) break
end <- end + 1
}
R
to apply a function to every memberR
function lapply
does this without writing out the entire loopR
lapply(data,function)
## What is the return type do you think?
results_l <- lapply(mtcars,median)
print(results_l)
## What is the return type do you think?
results_s <- sapply(mtcars,median)
print(results_s)
R
is declared using the syntaxfunction(parameter list){
function body
}
my_first_function <- function(){
print("Hello!")
}
my_first_function()
my_second_function <- function(a,b,c){
print(a * b + c)
}
my_second_function(1,2,3)
R
function, use the return
functionreturn (x)
R
function will return the value of the last expression of the function by defaultexplicit_return <- function(a,b)
{
return (a %/% b + a %% b)
}
print(explicit_return(20,3))
implicit_return <- function(a,b)
{
a %/% b + a %% b
}
print(implicit_return(20,3))
R
provides a wide variety of parameter optionsR
also allows a list to provide the arguments to a function, using the do.call
function
do.call(function_name, list_of_arguments)
param_example <- function(a, b = 0, c = 1){
result <- if (b == 0){
a / c
} else {
a / b
}
}
print(param_example(20))
print(param_example(20,c=2))
print(param_example(20,c=2,b=5))
print(param_example(20,2,5))
R
is a bit unique in that keyword parameters don't have to be completely spelled out when usedkeywords <- function(a, power=2, d = 3, donut = 5)
{
a ^ power + d * donut
}
print(keywords(2))
print(keywords(2,p=3))
print(keywords(2,d=3))
print(keywords(2,do=3))
keywords_trouble <- function(a, power=2, dollop = 3, donut = 5)
{
a ^ power + dollop * donut
}
print(keywords_trouble(2,d=5))
print(keywords_trouble(2,do=5))
print(keywords_trouble(2,dol=5))
R
are not evaluated until they are absolutely neededforce
functionR
are evaluated with respect to the current functionlazee <- function(a, b)
{
"I don't use my parameters"
}
print("String" * "string")
print(lazee("String" * "string",3))
not_lazee <- function(a, b,....)
{
print(length(list(....)))
force(a)
"I don't use my parameters"
}
print("String" * "string")
print(not_lazee("String" * "string",3,43))
lazier <- function(a,b = 2*a)
{
a + b
}
print(lazier(3))
print(lazier(3,4))
laziest <- function(command = ls())
{
var1 <- 2
var2 <- 3
command
}
print(laziest())
cat("\n")
print(laziest(ls()))
R
to name a function such that it can be called as arg FUNCTION_NAME arg
%
) is an infix function`%FUNCTION%` <- function(a,b){}
`%+%` <- function(a,b){
paste(a,b)
}
print("String" %+% "another")
print("String" %+% 45)
print(45 %+% "String")
#`% %` <- paste -- this works too
`% %` <- function(a,b){
paste(a,b)
}
print("String" % % "another")
print("String" % % 45)
print(45 % % "String")
names(vec) <- c(NAMES)
`FUNCTION_NAME<-` <- function(object,value){}
`multiply_first<-` <- function(x,value)
{
x[1] <- x[1] * value
x
}
vec_to_change <- c(1,2,3,4)
print(vec_to_change)
multiply_first(vec_to_change) <- 4
print(vec_to_change)
multiply_first(vec_to_change) <- 2
print(vec_to_change)
R
is just a call to a function`+` <- function(a,b){ a - b}
print(3 + 4)
print(`+`(3,4))
cat("\n")
vec_again <- 10:15
print(vec_again[2])
print(`[`(vec_again,2))
`+` <- function(a,b){ a - b}
print(3 + 4)
print(100+1)
rm(`+`)
cat("\n")
print(3 + 4)
print(100+1)
`[` <- function(obj,index){
"Sorry, you can't do that"
}
print(vec_again[2])
print(vec_again[[2]])
rm(`[`)
cat("\n")
print(vec_again[2])
R
supports three different types of objects, all declared and used in different waysR
S
languagestructure
function and assign the results to a variableclass
function to give an existing variable a class attributemy_first_instance <- structure(1:5,class="specialVector")
print(my_first_instance)
print(str(my_first_instance))
my_second_instance <- list(a_member = 2, another= "A String")
print(my_second_instance)
class(my_second_instance) <- "listClass"
print(str(my_second_instance))
structure
or class
inside of a functionclass_name <- function(parameters){
structure(list(parameters),class="class_name")
}
vehicle <- function(n_wheels,color){
structure(list(m_n_wheels = n_wheels, m_color = color ),
class="vehicle")
}
myCar <- vehicle(4,'black')
print(class(myCar))
child_class <- function(parameters)
{
self <- parent_class(parameters)
class(self) <- append("child_class",class(self))
self
}
car <- function(color){
self <- vehicle(4,color)
class(self) <- append("car",
class(self))
self
}
my_new_car <- car('black')
print(class(my_new_car))
R
uses a style of OOP known as genericst(df) # actually t.data.frame(df)
mm <- as.data.frame(matrix(1:20,ncol=4))
print(t(mm))
print(t.data.frame(mm))
print(t)
print(t.data.frame)
UseMethod
function denotes that this function should actually dispatch to a more appropriate function, based on the object that was passed int
might look liket <- function(obj){
UseMethod("t")
}
function_name.class_name
function_name.default
can be defined to be run in the event no match is foundprint(my_new_car)
print.vehicle <- function(x)
{
"My vehicle is " % % x[['m_color']] % % "in color and has" % % x$m_n_wheels % % "wheels."
}
print(my_new_car)
#print.vehicle <- print.default
rm(print.vehicle)
print(my_new_car)
makeNoise <- function(x){
print(class(x))
UseMethod("makeNoise")
}
makeNoise.vehicle <-function(x){
"Generic Vehicle Noise"
}
makeNoise.car <- function(x){
"BEEP BEEP"
}
makeNoise.default <- function(x){
"You can't make a noise"
}
print(makeNoise(myCar))
print(makeNoise(my_new_car))
print(makeNoise("Random String"))
new
functionslots
in R
)contains
keywordR