Introduzione ad R

Alla fine di questa puntata…

  • dovreste avere un’idea della storia, della “filosofia”, dei pro e contro di R
  • dovreste avere un’idea delle risorse disponibili e di dove reperirle
  • dovreste avere una “certa” familiarità con l’ambiente di lavoro R-Studio
  • dovreste avere imparato a chiedere aiuto

e molto probabilmente…

  • potreste chiedervi “ma fa veramente al caso mio?”

Prima di cominciare… le presentazioni

Di cosa si tratta?

  • un ambiente integrato per l’analisi dei dati (numerica, tabellare e grafica)
  • un linguaggio a tutti gli effetti
  • inspirato al linguaggio S (sviluppato da John Chambers presso gli AT&T Laboratories, con il contributo di Douglas Bates, Rick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and Allan Wilks)
  • il progetto parte nel 1997 su iniziativa di Robert Gentleman e Ross Ihaka (“R & R”) del Statistics Department dell’Università di Auckland (Nuova Zelanda)

Pro e contro

Punti di forza:

  • Open source (GNU GpL)
  • Offre una varietà di tecniche statistiche sia di base che avanzate
  • Grafica avanzata e personalizzabile
  • Estensibile
  • Veloce prototipazione
  • Multipiattaforma (ambiente, dati e script)
  • Ricchezza delle librerie aggiuntive
  • Possibilità di utilizzare codice C, Fortran, ecc.
  • Gestione dati completamente in memoria

Punti di debolezza:

  • Curva di apprendimento ripida
  • Lentezza (non compilato)
  • Ambiente non user–friendly
  • Gestione dell’output complessa
  • Gestione dati completamente in memoria

Caratteristiche

Linguaggio:

  • di tipo espressione
  • funzionale
  • orientato agli oggetti

Modalità d’uso:

  • interattiva
  • programmazione

Da non dimenticare:

  • case–sensitive
  • \(>\) prompt principale
  • \(+\) prompt di continuazione istruzione

Quanta (troppa?) roba

Sys.Date()
[1] "2025-02-21"
nrow(available.packages())

18897

Ma ci sono ormai molte altre fonti (GitHub e dintorni):

install.packages("devtools")
?devtools::install_github

O anche:

install.packages("remotes")
?remotes::install_github

Un’alternativa recente per installare pacchetti da fonti multiple:

(sembrerebbe più agevole, ma ancora da esplorare per scaricare package da diverse fonti)

Come installare R

nrow(getCRANmirrors())
[1] 94
table(getCRANmirrors()$Country)

             0-Cloud    0-Cloud-East-Asia            Argentina 
                   1                    1                    1 
           Australia              Austria              Belgium 
                   3                    1                    2 
              Brazil             Bulgaria               Canada 
                   3                    1                    3 
               Chile                China             Colombia 
                   1                   13                    1 
          Costa Rica               Cyprus       Czech Republic 
                   1                    1                    1 
             Denmark              Ecuador              Finland 
                   1                    1                    1 
              France              Germany               Greece 
                   3                    8                    1 
             Hungary              Iceland                India 
                   1                    1                    2 
           Indonesia                 Iran                Italy 
                   1                    1                    2 
               Japan                Korea               Mexico 
                   1                    1                    2 
             Morocco          Netherlands          New Zealand 
                   1                    2                    1 
              Norway               Poland             Portugal 
                   1                    1                    1 
              Russia         South Africa                Spain 
                   1                    1                    2 
              Sweden          Switzerland               Taiwan 
                   1                    2                    1 
              Turkey                   UK United Arab Emirates 
                   1                    3                    1 
             Uruguay                  USA            Worldwide 
                   1                   11                    1 
  • http://cran.stat.unipd.it/

Documentazione e dintorni

Documentazione ufficiale:

Task Views:

The R Journal:

diverse mailing list generali e Special Interest Group (SIG):

Alcune risorse interessanti:

Cosa si dice in giro?

Benvenuti…

… si fa per dire:

Benvenuti?

Ambienti (?semplificati?) di utilizzo

Ambienti multipiattaforma:

Va un po’ meglio?

Benvenuti?

Ricerca nell’help

Due possibili modalità per effettuare la ricerca nell’help per parola chiave:

help.search("regression")
??regression

Per nome della funzione (anche qui due possibili modalità):

help(mean)
?mean

Per l’help di alcune funzioni (quelle di programmazione e gli operatori) è necessario usare gli apici (singoli o doppi):

?for
?"for"

E’ possibile cercare tutti gli oggetti (sulla “search list”) che contengono una data parola:

apropos("mean")
 [1] ".colMeans"     ".rowMeans"     "colMeans"      "kmeans"       
 [5] "mean"          "mean.Date"     "mean.default"  "mean.difftime"
 [9] "mean.POSIXct"  "mean.POSIXlt"  "rowMeans"      "weighted.mean"

così come cercare in che posizione si trovano:

find("mean")
[1] "package:base"
find("kmeans")
[1] "package:stats"

Le funzioni: istruzioni per l’uso

Gli esempi della funzioni possono essere provati usando la funzione example:

example(mean)

mean> x <- c(0:10, 50)

mean> xm <- mean(x)

mean> c(xm, mean(x, trim = 0.10))
[1] 8.75 5.50
example(plot)

plot> Speed <- cars$speed

plot> Distance <- cars$dist

plot> plot(Speed, Distance, panel.first = grid(8, 8),
plot+      pch = 0, cex = 1.2, col = "blue")


plot> plot(Speed, Distance,
plot+      panel.first = lines(stats::lowess(Speed, Distance), lty = "dashed"),
plot+      pch = 0, cex = 1.2, col = "blue")


plot> ## Show the different plot types
plot> x <- 0:12

plot> y <- sin(pi/5 * x)

plot> op <- par(mfrow = c(3,3), mar = .1+ c(2,2,3,1))

plot> for (tp in c("p","l","b",  "c","o","h",  "s","S","n")) {
plot+    plot(y ~ x, type = tp, main = paste0("plot(*, type = \"", tp, "\")"))
plot+    if(tp == "S") {
plot+       lines(x, y, type = "s", col = "red", lty = 2)
plot+       mtext("lines(*, type = \"s\", ...)", col = "red", cex = 0.8)
plot+    }
plot+ }


plot> par(op)

plot> ##--- Log-Log Plot  with  custom axes
plot> lx <- seq(1, 5, length.out = 41)

plot> yl <- expression(e^{-frac(1,2) * {log[10](x)}^2})

plot> y <- exp(-.5*lx^2)

plot> op <- par(mfrow = c(2,1), mar = par("mar")-c(1,0,2,0), mgp = c(2, .7, 0))

plot> plot(10^lx, y, log = "xy", type = "l", col = "purple",
plot+      main = "Log-Log plot", ylab = yl, xlab = "x")

plot> plot(10^lx, y, log = "xy", type = "o", pch = ".", col = "forestgreen",
plot+      main = "Log-Log plot with custom axes", ylab = yl, xlab = "x",
plot+      axes = FALSE, frame.plot = TRUE)


plot> my.at <- 10^(1:5)

plot> axis(1, at = my.at, labels = formatC(my.at, format = "fg"))

plot> e.y <- -5:-1 ; at.y <- 10^e.y

plot> axis(2, at = at.y, col.axis = "red", las = 1,
plot+      labels = as.expression(lapply(e.y, function(E) bquote(10^.(E)))))

plot> par(op)
example(plotmath)

pltmth> require(graphics)

pltmth> x <- seq(-4, 4, length.out = 101)

pltmth> y <- cbind(sin(x), cos(x))

pltmth> matplot(x, y, type = "l", xaxt = "n",
pltmth+         main = expression(paste(plain(sin) * phi, "  and  ",
pltmth+                                 plain(cos) * phi)),
pltmth+         ylab = expression("sin" * phi, "cos" * phi), # only 1st is taken
pltmth+         xlab = expression(paste("Phase Angle ", phi)),
pltmth+         col.main = "blue")


pltmth> axis(1, at = c(-pi, -pi/2, 0, pi/2, pi),
pltmth+      labels = expression(-pi, -pi/2, 0, pi/2, pi))

pltmth> ## How to combine "math" and numeric variables :
pltmth> plot(1:10, type="n", xlab="", ylab="", main = "plot math & numbers")


pltmth> theta <- 1.23 ; mtext(bquote(hat(theta) == .(theta)), line= .25)

pltmth> for(i in 2:9)
pltmth+     text(i, i+1, substitute(list(xi, eta) == group("(",list(x,y),")"),
pltmth+                             list(x = i, y = i+1)))

pltmth> ## note that both of these use calls rather than expressions.
pltmth> ##
pltmth> text(1, 10,  "Derivatives:", adj = 0)

pltmth> text(1, 9.6, expression(
pltmth+  "             first: {f * minute}(x) " == {f * minute}(x)), adj = 0)

pltmth> text(1, 9.0, expression(
pltmth+  "     second: {f * second}(x) "        == {f * second}(x)), adj = 0)

pltmth> ## note the "{ .. }" trick to get "chained" equations:
pltmth> plot(1:10, 1:10, main = quote(1 <= {1 < 2}))


pltmth> text(4, 9, expression(hat(beta) == (X^t * X)^{-1} * X^t * y))

pltmth> text(4, 8.4, "expression(hat(beta) == (X^t * X)^{-1} * X^t * y)",
pltmth+      cex = .8)

pltmth> text(4, 7, expression(bar(x) == sum(frac(x[i], n), i==1, n)))

pltmth> text(4, 6.4, "expression(bar(x) == sum(frac(x[i], n), i==1, n))",
pltmth+      cex = .8)

pltmth> text(8, 5, expression(paste(frac(1, sigma*sqrt(2*pi)), " ",
pltmth+                             plain(e)^{frac(-(x-mu)^2, 2*sigma^2)})),
pltmth+      cex = 1.2)

pltmth> ## some other useful symbols
pltmth> plot.new(); plot.window(c(0,4), c(15,1))


pltmth> text(1, 1, "universal", adj = 0); text(2.5, 1,  "\\042")

pltmth> text(3, 1, expression(symbol("\042")))

pltmth> text(1, 2, "existential", adj = 0); text(2.5, 2,  "\\044")

pltmth> text(3, 2, expression(symbol("\044")))

pltmth> text(1, 3, "suchthat", adj = 0); text(2.5, 3,  "\\047")

pltmth> text(3, 3, expression(symbol("\047")))

pltmth> text(1, 4, "therefore", adj = 0); text(2.5, 4,  "\\134")

pltmth> text(3, 4, expression(symbol("\134")))

pltmth> text(1, 5, "perpendicular", adj = 0); text(2.5, 5,  "\\136")

pltmth> text(3, 5, expression(symbol("\136")))

pltmth> text(1, 6, "circlemultiply", adj = 0); text(2.5, 6,  "\\304")

pltmth> text(3, 6, expression(symbol("\304")))

pltmth> text(1, 7, "circleplus", adj = 0); text(2.5, 7,  "\\305")

pltmth> text(3, 7, expression(symbol("\305")))

pltmth> text(1, 8, "emptyset", adj = 0); text(2.5, 8,  "\\306")

pltmth> text(3, 8, expression(symbol("\306")))

pltmth> text(1, 9, "angle", adj = 0); text(2.5, 9,  "\\320")

pltmth> text(3, 9, expression(symbol("\320")))

pltmth> text(1, 10, "leftangle", adj = 0); text(2.5, 10,  "\\341")

pltmth> text(3, 10, expression(symbol("\341")))

pltmth> text(1, 11, "rightangle", adj = 0); text(2.5, 11,  "\\361")

pltmth> text(3, 11, expression(symbol("\361")))

Per alcune funzioni è disponibile un insieme di esempi più esteso accessibile attraverso il comando

demo()
demo(graphics)

Per visualizzare la lista di funzioni con demo associate (dipende anche da quali librerie sono installate)

demo()

Per visualizzare le demo in tutte le librerie installate

demo(package = .packages(all.available = TRUE))

Le funzioni: differenza tra definizione ed utilizzo

Digitando il nome di una funzione è possibile visualizzare il codice associato:

diag
function (x = 1, nrow, ncol, names = TRUE) 
{
    if (is.matrix(x)) {
        if (nargs() > 1L && (nargs() > 2L || any(names(match.call()) %in% 
            c("nrow", "ncol")))) 
            stop("'nrow' or 'ncol' cannot be specified when 'x' is a matrix")
        if ((m <- min(dim(x))) == 0L) 
            return(vector(typeof(x), 0L))
        y <- x[1 + 0L:(m - 1L) * (dim(x)[1L] + 1)]
        if (names) {
            nms <- dimnames(x)
            if (is.list(nms) && !any(vapply(nms, is.null, NA)) && 
                identical((nm <- nms[[1L]][seq_len(m)]), nms[[2L]][seq_len(m)])) 
                names(y) <- nm
        }
        return(y)
    }
    if (is.array(x) && length(dim(x)) != 1L) 
        stop("'x' is an array, but not one-dimensional.")
    if (missing(x)) 
        n <- nrow
    else if (length(x) == 1L && nargs() == 1L) {
        n <- as.integer(x)
        x <- 1
    }
    else n <- length(x)
    if (!missing(nrow)) 
        n <- nrow
    if (missing(ncol)) 
        ncol <- n
    .Internal(diag(x, n, ncol))
}
<bytecode: 0x7f8651780388>
<environment: namespace:base>

Alcune funzioni sono di tipo generico (che lavorano in modo differente a seconda del tipo di argomento passato in input).

mean
function (x, ...) 
UseMethod("mean")
<bytecode: 0x7f8655825580>
<environment: namespace:base>

Per vedere quali funzioni specifiche sono disponibili per i vari oggetti si può utilizzare la funzione methods

methods(mean)
[1] mean.Date     mean.default  mean.difftime mean.POSIXct  mean.POSIXlt 
[6] mean.quosure*
see '?methods' for accessing help and source code

La funzione mean.default è quella che viene chiamata nel caso in cui non sia disponibile una funzione specifica per il tipo di argomento passato in input:

mean.default
function (x, trim = 0, na.rm = FALSE, ...) 
{
    if (!is.numeric(x) && !is.complex(x) && !is.logical(x)) {
        warning("argument is not numeric or logical: returning NA")
        return(NA_real_)
    }
    if (isTRUE(na.rm)) 
        x <- x[!is.na(x)]
    if (!is.numeric(trim) || length(trim) != 1L) 
        stop("'trim' must be numeric of length one")
    n <- length(x)
    if (trim > 0 && n) {
        if (is.complex(x)) 
            stop("trimmed means are not defined for complex data")
        if (anyNA(x)) 
            return(NA_real_)
        if (trim >= 0.5) 
            return(stats::median(x, na.rm = FALSE))
        lo <- floor(n * trim) + 1
        hi <- n + 1 - lo
        x <- sort.int(x, partial = unique(c(lo, hi)))[lo:hi]
    }
    .Internal(mean(x))
}
<bytecode: 0x7f86580cfa18>
<environment: namespace:base>