Lists

Οι λιστες (list) ειναι μια από τις ισχυρότερες δομές δεδομένων στην R. - είναι γενικές, δηλαδή μπορεί να περιέχουν δεδομένα διαφορετικού τύπου (κάτι που δεν έχουν τα vectors και matrices) - οι καταχωρήσεις μπορεί να έχουν όνομα (ισχύει και στα vectors αυτό) - οι καταχωρήσεις μπορεί να έχουν διαφορετικό μήκος (κάτι που δεν ισχύει στα data.frames)

Άρα μπορούμε να πούμε ότι οι list ειναι δομές δεδομένων που επιτρέπουν την αποθήκευση διαφορετικού τύπου μεταβλητών, οι καταχωρήσεις ειναι ονοματισμένες και η κάθε καταχώρηση μπορεί να έχει διαφορετικό μήκος.

Κατασκευή

a = list() # άδεια λίστα. H a ειναι μια λίστα που δεν περιέχει τίποτα

a = list(x=c(1,2,3)) # Η a ειναι μια λίστα που περιέχει ένα αντικείμενο, το x, που ειναι vector από 3 στοιχεία

a = list(x = c(1,2,3), y=c("A")) # Η a περιέχει 2 στοιχεία, το x και y, που το καθένα ειναι vector
## από αριθμούς και χαρακτήρες αντίστοιχα. 

a = list( x = list(x=c("A"), z=c(1,2,3)), y = "kalimera") # Η a είναι μια λίστα , που περιέχει μια λίστα (την x), και ένα character-string το y. Η λιστα x, περιέχει δύο vectors

a = list(c(1,2,3)) # λίστα που περιέχει ένα vector, μη ονοματισμένο (χωρίς όνομα)

Βλέπετε από τα παραπάνω παραδείγματα πόσο ισχυρές ειναι οι λίστες.

Πρόσβαση στα στοιχεία της λίστας

Στις λίστες έχουμε δύο operators (δύο τρόπους) να έχουμε πρόσβαση στα στοιχεία της. Το [[ ]] και το []. Θεωρείστε το παρακάτω παράδειγμα.

x = list(a=c(1,2,3), b=c("A", 'b'))

Tότε, το πρώτο στοιχείο της λίστας x, ειναι το a, και το δευτερο στοιχείο της λίστας x είναι το b.

Έχουμε λοιπόν:

## first element
## Πρόσβαση με το όνομα του στοιχείου
x$a ## το στοιχείο του x, που έχει το όνομα a
## [1] 1 2 3
## Πρόσβαση με indexes

## Ώς vector
x[[1]] ## πρώτο στοιχείο ειναι το c(1,2,3) ΕΙΝΑΙ vector
## [1] 1 2 3
## Ως λίστα
x[1]   ## πρώτο στοιχείο ΕΙΝΑΙ ΛΙΣΤΑ
## $a
## [1] 1 2 3

ΠΡΟΣΟΧΗ! Όταν έχουμε πρόσβαση ως λιστα δηλαδή με το [ ] operator, τότε μπορούμε να κάνουμε slice, δηλαδή να πάρουμε και πανω από ένα στοιχεία. Για παράδειγμα

a = list(x=c(1,2), y="a", z=c(5,4,5,3))

## μία λίστα με τα 2 πρώτα στοιχεία
a[1:2]
## $x
## [1] 1 2
## 
## $y
## [1] "a"
## μία λίστα με τα στοιχεία 1,3
a[c(1,3)]
## $x
## [1] 1 2
## 
## $z
## [1] 5 4 5 3

ΠΡΟΣΟΧΗ!!! Το a[[1:2]] ίσως δεν βγάλει λάθος, όμως ειναι αποτέλεσμα χωρίς νόημα!

a[[c(1,2)]]
## [1] 2

Προσέξτε τις διαφορές:

a = list(x=c(1,2,3), y=c("a", "b"))
## Το πρώτο στοιχείο (x)
a$x
## [1] 1 2 3
## Επίσης το πρώτο στοιχείο
a[["x"]] ## θα ειναι vector
## [1] 1 2 3
## Επίσης το πρώτο στοιχείο 
a["x"] # Θα ειναι λίστα
## $x
## [1] 1 2 3

Παρατηρήστε την διαφορά

(χωρίς και με εισαγωγικά)

To γεγονός ότι έχουμε πρόσβαση με τα ονόματα, μας επιτρέπει να τις χρησιμοοποιήσουμε ως associative arrays (hashes)

a=list(antonis=29, vaggelis=54, kostas=33)
# όπου σε κάθε όνομα έχουμε αποθηκευσει την ηλικία
# Ας υποθέσουμε ότι η λίστα έίχε εκατομμύρια καταχωρήσεις (αντί για μόνο 3)

Στην C δεν υπάρχει η δυαντότητα αυτή. Εκεί για να είχαμε τη σχέση μεταξύ ονόματος και ηλικίας θα έπρεπε:

nam = c("antonis", "vaggelis", "kostas")
age = c(29, 54, 33)

# όμως για να βρούμε τι ηληκία έχει ο Κώστας, θα πρέπει να διατρέχουμε όλη τη λίστα
# Στην R απλά θα γράφαμε
a$kostas
## [1] 33

Ένα δεύτερο συνηθισμένο παράδειγμα αφορά στην έκφραση γονιδίων. Σε έναν οργανισμό Α, που έχει 20,000 γονίδια, τα γονίδια a1, a2, a7 μας ενδιαφέρουν επειδή σχετίζονται με μία ασθένεια. Οι εκφράσεις γονιδίων στον Α, υπάρχουν σε μια λίστα ΕΑ. Για παράδειγμα, EA[["a1"]], δίδει την έκφραση του a1, στον Α. Αν θέλουμε να δούμε σε έναν οργανισμό Β, την έκφραση των τριων αυτών γονιδίων a1, a2, a7, θα πρέπει να διατρέξουμε όλη την λίστα των γονιδίων ΕΒ του B ώστε να βρούμε ποιες τιμές έκφρασης αντιστοιχούν στα γονίδια a1, a2, a7. Αν όμως έχουμε ονοματίσει την λίστα γονιδίων, τότε μπορούμε πολύ εύκολα να ζητήσουμε τις εκφράσεις ως εξής ΕΒ[["a1"]] ΕΒ[["a2"]] ΕΒ[["a7"]].

Γενικά οι ονοματισμένες λίστες ειναι πολύ χρήσιμες στην βιοπληροφορική

Ονοματισμένα vectors

Και τα vectors μπορούν να φέρουν ονόματα στις τιμές που περιέχουν. Για παράδειγμα,

a = c(12,21,13) ## δεν φέρει ονόματα
names(a) = c("Gene1", "Gene2", "Gene3")
a
## Gene1 Gene2 Gene3 
##    12    21    13
a["Gene1"] == a[1]
## Gene1 
##  TRUE

Matrix

Η δομή matrix ειναι μια δισδιάστατη δομή δεδομένων. Μοιάζει με τα vectors. Έτσι:

  • Η δομή matrix έχει πάντα τον ίδιο τυπο δεδομένων (πχ chr, numeric)

Κατασκευή

Με default τιμή

## όλα τα κελιά της m θα έχουν την τιμή 0
m = matrix(0, nrow=5, ncol=3)
m
##      [,1] [,2] [,3]
## [1,]    0    0    0
## [2,]    0    0    0
## [3,]    0    0    0
## [4,]    0    0    0
## [5,]    0    0    0

Με vector τιμών

m1 = matrix(1:10, nrow=5, ncol=2) ## δεκα τιμές σε δέκα κελιά
m1
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
m2 = matrix(1:10, nrow=5, ncol=2, byrow=TRUE)
m2
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8
## [5,]    9   10
m3 = matrix(1:10, nrow=5, ncol=2, byrow=FALSE)
m3
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
# Ποια ειναι η default συμπεριφορά της R για το πώς να βάλει τις τιμές στα κελιά;

κυκλικά με vector τιμών

m1 = matrix(1:2, nrow=2, ncol=5, byrow=TRUE)
m1
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    1    2    1
## [2,]    2    1    2    1    2
m2 = matrix(1:2, nrow=2, ncol=5, byrow=FALSE)
m2
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    1    1    1    1
## [2,]    2    2    2    2    2

Τι γίνεται αν το μέγεθος του matrix δεν ειναι πολλαπλάσιο του μήκους του vector

m = matrix(1:3, nrow=2, ncol=5)
## Warning in matrix(1:3, nrow = 2, ncol = 5): data length [3] is not a sub-
## multiple or multiple of the number of rows [2]
m
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    2    1    3
## [2,]    2    1    3    2    1

Τι γίνεται αν το μέγεθος του matrix είναι μικρότερο από το μήκος του vector

m = matrix(1:15, nrow=2, ncol=5)
## Warning in matrix(1:15, nrow = 2, ncol = 5): data length [15] is not a sub-
## multiple or multiple of the number of rows [2]
m
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10

Ονόματα γραμμών και στηλών

Στα matrix μπορούμε να έχουμε ονόματα γραμμών και στηλών

m = matrix(1:10, nrow=2, ncol=5, byrow=TRUE)
colnames(m) = letters[1:5]
rownames(m) = c("a", "aa")
m
##    a b c d  e
## a  1 2 3 4  5
## aa 6 7 8 9 10

Πρόσβαση στα στοιχεία του matrix

Για να έχουμε πρόσβαση στα στοιχεία του matrix χρησιμοποιούμε τον operator [,]. Πριν το κόμμα ‘,’ αναφερόμαστε στις γραμμές και μετά το κόμμα στις στήλες. Για παράδειγμα:

a = matrix(1:10, nrow=2)
a[1,2] ## στοιχείο 1ης γραμμής 2ης στήλης
## [1] 3
a[1, 1:2] ## στοιχεία 1ης γραμμής, στήλης 1 και 2
## [1] 1 3
a[1:2, c(1,2,4)] # στοιχεία γραμμών 1,2 και στηλών 1,2,4. Θα ειναι matrix 2x3. 
##      [,1] [,2] [,3]
## [1,]    1    3    7
## [2,]    2    4    8

Αν υπάρχουν ονόματα γραμμών στηλών, τότε η πρόσβαση μπορεί να γίνει και με τα ονόματα

a = matrix(1:10, nrow=2)
colnames(a) <- letters[1:5]
rownames(a) <- c("x", "y")
a[,"c"] ## στοιχείο 1ης γραμμής 2ης στήλης
## x y 
## 5 6
a["x",]
## a b c d e 
## 1 3 5 7 9

ΠΑΡΑΤΗΡΗΣΗ: Για να πάρουμε όλη την γραμμή ή την στήλη χρησιμοποιούμε ‘άδεια’ θέση στις γραμμές ή στις στήλες. Δείτε το παράδειγμα παραπάνω.

Data frames

To data.frame μοιάζουν με matrix όμως…

  • στις στήλες τους μπορούν να περιέχουν δεδομένα διαφορετικών τύπων. Για παράδειγμα, η πρώτη στήλη μπορεί να περιέχει αριθμούς, ενώ η δευτερη στήλη χαρακτήρες

Ο πιο συνηθισμένος τρόπος να κατασκευάσουμε data.frame είναι με την συνάρτηση read.table, όπου διαβάζουμε δεδομένα που βρίσκονται σε αρχειο και έχουν μορφή πίνακα

##a = matrix(rnorm(20000, 1000, 10), nrow=200)
##colnames(a) = paste("Individual",1:100, sep="")
##rownames(a) = paste("Gene", 1:200, sep="")
##write.table(a, file="geneExpressionExample.csv", sep="\t", col.names=TRUE, row.names = F, quote = F)

## Διαβάζουμε το αρχείο με την συνάρτηση read.table
## Έχει επικεφαλίδα, άρα βάζουμε header=TRUE
a = read.table(file="geneExpressionExample.csv", header=TRUE)
dim(a) # οι Διαστάσεις του a
## [1] 200 100
head(a) # οι πρώτες έξι γραμμές