TP1 Exercices Correction
TP1 Exercices Correction
TP1 Exercices Correction
Ce polycopié rassemble différents exercices vous permettant d’apprendre à utiliser le langage de programmation
R. Ces exercices sont de difficultés variables. Il est important de réaliser les exercices les plus simples avant
de débuter les plus difficiles.
Exercice 1
Exercice 2
Exercice 3
1. Créer le vecteur vec1 contenant tous les multiples de 2 compris entre 1 et 50.
2. Créer le vecteur vec2 contenant 3 fois chacun des 10 chiffres (soit 0, 0, 0 ; 1, 1, 1 ; 2, 2, 2 ; 3, 3, 3 ;
etc.). Indice: rep()
3. Créer le vecteur vec3 contenant une fois la lettre A, deux fois la lettre B, trois fois la lettre C . . . et 26
fois la lettre Z. Quelle est la longueur de cette suite ? Indice: LETTERS; length()
1
Pensez à bien regarder l’aide des fonctions. Par exemple, pour la fonction rep regardez bien la différence
entre les paramètres each et times ; vous pouvez copier-coller les lignes d’exemple pour bien comprendre
chaque paramètre.
#1
vec1 = seq(from=2, to=50, by=2 )
#2
vec2 = rep(c(0:9), each=3)
#3
vec3 = rep(LETTERS, times = c(1:26))
length(vec3)
Exercice 4
Exercice 5 : Facteurs
Exercice 6 : Matrices
#2
A = matrix(a, ncol = 10, nrow = 10)
2
#3
dim(A)
ncol(A)
nrow(A)
#4
B = t(A)
#5
line1 = A[seq(2,10,2),]
col0 = B[,seq(1,10,2)]
#2
y = as.data.frame(x)
#3
z1 = y[c(1:3) ,]
z2 = y[c(8:10),]
class(z1)
class(z2)
#4
x$chiffre = 1:26
#5
as.data.frame(x)
3
Exercice final classe objet : Student’s Sleep Data
1. Executez la commande data(sleep). Nous venons de charger en mémoire l’un des nombreux jeux de
données distribués avec R ! Profitez de l’aide sur ce jeu de données pour en apprendre un peu plus
(?sleep) ! Tous les jeux de données disponibles avec l’installation de base de R sont accessibles en
tapant data().
2. Quel est le type de l’objet sleep ?
3. Quelle fonction vous permet d’obtenir rapidement le nombre d’individus par groupe ? Executez la.
4. Combien y-a-t-il de valeurs négatives dans le groupe 1 ? Indice : which()
5. Soit s un vecteur représentant le sexe des individus : s = rep(c("f","m","m","f","m","f","m","m","f","m"),2).
Combinez l’objet sleep et le vecteur s dans une nouvelle matrice sleep2. Indice : cbind()
6. Quelles sont les noms des colonnes de la matrice sleep2 ? Renommez la dernière colonne en ‘sex’.
Indice : colnames()
7. Combien y-a-t-il de femmes et d’hommes dans chacun des groupes ?
#1
data(sleep)
#2
typeof(sleep); class(sleep)
#3
table(sleep$group)
#4
length(which(sleep$extra < 0))
#5
s = rep(c("f","m","m","f","m","f","m","m","f","m"),2)
sleep2 = cbind(sleep, s)
#6
colnames(sleep2)
colnames(sleep2)[4] = "sex"
#7
table(sleep2$s, sleep2$group)
Il est possible de lire les données stockées dans des fichiers sous format txt grâce, entre autres, aux fonctions
suivantes: read.table(), read.csv(), read.csv2() et scan(). Par ailleurs, la fonction read.xls() (resp.
write.xls()) du package gdata fournit les outils pour lire (resp. écrire) des fichiers au format Excel. Il
existe aussi la fonction read.xlsx (resp. write.xlsx) du package xlsx.
(Récupérez les fichiers demandés sur le site xxxxxxx). Vous pouvez ouvrir au préalable ces différents fichiers
dans un éditeur de texte afin d’identifier le séparateur de colonnes, le symbole de décimale, comment sont
définies les valeurs manquantes etc . . .
1. Importez dans une variable nommée A le jeu de données nommé auto2004_original.txt. **Indice :
le séparateur de colonne ‘tabulation’ correspond à ‘’ en informatique*
2. Importez dans une variable nommée B le jeu de données auto2004_sans_nom.txt.
3. Importez dans une variable nommée C le jeu de données auto2004_virgule.txt.
4. Importez dans une variable nommée D le jeu de données auto2004_don_manquante.txt. Combien de
valeurs manquantes sont contenues dans le fichier ?
5. Importez dans une variable nommée E le jeu de données auto2004_don_manquante(99999).txt.
6. Quel est le mode des objets créés par la fonction read.table() ?
4
Indice : help("read.table"), help("is.na")
#1
A = read.table(file="auto2004_original.txt", sep="\t", header = TRUE)
#2
B = read.table(file="auto2004_sans_nom.txt", sep="\t", header = FALSE)
#3
C = read.table(file="auto2004_virgule.txt", sep="\t", header = TRUE, dec = ",")
#4
D = read.table(file="auto2004_don_manquante.txt", header = TRUE, sep="\t", na.strings = "")
nb = length(which(is.na(D) == TRUE))
#5
E = read.table(file="auto2004_don_manquante(99999).txt", header = TRUE, sep="\t", na.strings = "99999")
#6
class(E)
#1
write.table(A, file = "matrice.txt")
#2
write.table(A, file = "matrice.txt", row.names = FALSE, col.names = FALSE)
#3
save(A, file="matriceA.Rdata")
#4
C = load("matriceA.Rdata")
### la matrice A est rechargée.
### la variable C vaut "A"
#5
save(list = ls(), "données.Rdata")
5
Fonctions graphiques
#2
p = table(iris$Species)
#3
pie(p)
barplot(p)
#4
summary(iris)
#5
boxplot(iris[,1:4])
#6
boxplot(iris[,1:4], title="Iris Boxplot", outline=FALSE)
#7
par(mfrow=c(1,2))
boxplot(iris[,1:4], title="Iris Boxplot", outline=FALSE)
pie(p)
#8
pdf("plotIris.pdf")
par(mfrow=c(1,2))
6
boxplot(iris[,1:4], title="Iris Boxplot", outline=FALSE)
pie(p)
dev.off()
#9
plot(iris$Petal.Length, iris$Petal.Width)
#10
plot(iris$Petal.Length, iris$Petal.Width, cex=5)
plot(iris$Petal.Length, iris$Petal.Width, pch=17, col="red")
abline(h=1, lty=2)
#9
pairs(iris[,1:4], col=as.numeric(iris$Species), pch=16)
#10
pdf("pairs_iris.pdf")
pairs(iris[,1:4], col=as.numeric(iris$Species), pch=16)
dev.off()
d = density(airquality$Ozone, na.rm=TRUE)
lines(d)
Exercice 12 : for
1. Lisez l’aide sur la procédure permettant de réaliser des boucles indicées for (help("for")). Remarque
: demander de l’aide sur cette procédure avec la syntaxe ?for ne fonctionnera pas ! Pourquoi ?
2. Créer une boucle qui affiche l’indice i de l’itération en cours (10 itérations)
3. A l’aide d’une boucle, calculez la somme des entiers pairs compris entre 1 et 100.
7
#1
help("for")
#2
for (i in 1:10) print(i)
#3
somme = 0
for (i in seq(2,100,2)) {
somme = somme + i
}
somme
#2
x = 25
y = 0
if (x > 0){
y = x^2
}
else{
y = x^3
}
#3
for (i in -10:10){
x = i
y = 0
if (x > 0){
y = x^2
}
else{
y = x^3
}
print(paste(i, y, sep=" => "))
}
1. Créer une matrice matrice contenant des valeurs tirées aléatoirement de dimension 10 lignes x 10
colonnes et dont les éléments suivent une loi normale de moyenne nulle et de variance 2.32.
8
2. Afficher nombre d’éléments positifs et négatifs de la matrice. Remplacer les nombre négatifs par 0.
3. Afficher les marges de matrice (sommes des valeurs en lignes et en colonnes). Indice : apply, sum
4. Afficher la moyenne des lignes et des colonnes de la matrice.
5. Un autre moyen d’afficher rapidemment la somme/moyenne des lignes/colonnes d’une matrice, est
d’utiliser des fonctions R pré-existantes : rowSums, colSums, rowMeans, colMeans.
#1
matrice = matrix(rnorm(n=100, mean = 0, sd = 2.32),nrow = 10, ncol=10)
#2
nbPos = length(which(matrice > 0))
idxNeg = which(matrice < 0)
nbNeg = length(idxNeg)
matrice[idxNeg] = 0
#3
apply(matrice, 1, sum)
apply(matrice, 2, sum)
#4
apply(matrice, 1, mean)
apply(matrice, 1, mean)
#5
rowSums(matrice); colSums(matrice)
rowMeans(matrice); colMeans(matrice)
1. Exécutez les commandes data(iris) puis str(iris). Nous venons de charger en mémoire l’un des
nombreux jeux de données distribués avec R ! Profitez de l’aide sur ce jeu de données pour en apprendre
un peu plus sur les fleurs (?iris) ! Tous les jeux de données disponibles avec l’installation de base de
R sont accessibles en tapant data().
2. Créez la fonction moyenneET suivante et décryptez la :
moyenneET = function(i) c(moy = mean(iris[,i]), et = sd(iris[,i]) )
3. Afficher l’aide de la fonction apply. En utilisant cette fonction, calculez la moyenne et l’écart type des
colonnes numériques du dataset iris. Comparer le résultat avec celui obtenu par la foncion moyenneET.
Remarque : pour exécuter plusieurs commandes au sein d’une même fonction, il faut utiliser des accolades
{...}.
#1
data(iris)
str(iris)
moyenneET(2)
#2
moyenneET <- function(i) {
moy = mean(iris[,i])
et = sd(iris[,i])
9
return( c(moy = moy, et = et) )
}
#3
?apply
moy = apply(iris[,c(1,2,3,4)], 2, mean)
et = apply(iris[,c(1,2,3,4)], 2, sd)
moyenneET(1)
moyenneET(2)
moyenneET(3)
moyenneET(4)
Créer une fonction nommée somme qui calcule la somme de deux variables x et y passées en arguments.
somme = function(x, y){
resultat = x+y
return(resultat)
}
1. Choisir un nombre mystère entre 1 et 100, et le stocker dans un objet que l’on nommera nombre_mystere.
Ensuite, créer une boucle qui à chaque itération effectue un tirage aléatoire d’un entier compris entre 1
et 100. Tant que le nombre tiré est différent du nombre mystère, la boucle doit continuer. A la sortie
de la boucle, une variable que l’on appellera nb_tirages contiendra le nombre de tirages réalisés pour
obtenir le nombre mystère.
2. Utiliser le code de la question précédente pour réaliser la fonction trouver_nombre, qui, lorsqu’on lui
donne un nombre compris entre 1 et 100, retourne le nombre de tirages aléatoires d’entiers compris
entre 1 et 100 nécessaires avant de tirer le nombre mystère.
3. En utilisant une boucle for, faire appel 1000 fois à la fonction trouver_nombre() qui vient d’être créée.
A chaque itération, stocker le résultat dans un élément d’un vecteur que l’on appellera nb_essais_rep.
Enfin, afficher la moyenne du nombre de tirages nécessaires pour retrouver le nombre magique.
Indice : sample, while
# 1
nombre_mystere = 59
s = 0
nb_tirages = 0
while (s != nombre_mystere){
s = sample(1:100, 1)
nb_tirages = nb_tirages + 1
}
nb_tirages
# 2
trouver_nombre = function(nombre_mystere){
if (nombre_mystere >=1 & nombre_mystere <=100){
s = 0
10
nb_tirages = 0
while (s != nombre_mystere){
s = sample(1:100, 1)
nb_tirages = nb_tirages + 1
}
nb_tirages
}
else{
warning("Votre nombre doit être compris entre 1 et 100")
}
}
#3
nb_essais_rep = c()
for (i in seq(1000)){
tmp = trouver_nombre(39)
nb_essais_rep = c(nb_essais_rep, tmp)
}
mean(tmp)
#1
parseMail = function(email){
nom_prenom = unlist(strsplit(email, "@"))[1]
nom_prenom = unlist(strsplit(nom_prenom, "\\."))
prenom = nom_prenom[1]
nom = nom_prenom[2]
data.frame(prenom = prenom, nom = nom, email = email)
}
#2
11
emails.df = c()
for (m in emails){
df = parseMail(m)
emails.df = rbind(emails.df,df)
}
#2
lapply(twittos, function(twit){twit$screen_name})
#3
twittos_to_df = function(twit){
return(data.frame(twit))
}
#4
twittos_to_df(twittos[1])
res = lapply(twittos, twittos_to_df)
12
Exercices de Niveau Avancé
Exercice 21 : Layout
Les données old faithful geyser ont été collectées dans le cadre d’une étude du temps d’attente entre
deux éruptions et la durée des éruptions au sein du parc National de Yellowstone (USA). Ce jeu de données
est disponible sous R et est nommé faithful (package datasets). Le seuil critique d’attente au delà duquel
la probabilité que la prochaine éruption soit longue et forte est fixé à 63.
1. Télécharger et visualiser le jeu de données (fonction plot( )), en affichant également la limite des 63
secondes.
2. Calculer un vecteur vec de 100000 points correspondant à la loi normale de moyenne m et d’écart type
sd correspondant à la moyenne, et à l’écart type, des durées d’éruption.
3. Construire un histogramme de la durée d’éruption. Représenter l’histogramme en terme de densité
plutôt qu’en terme d’effectifs (axe Y). Ajouter un titre, nommer les axes et colorer les barres
de l’histogramme en vert et les traits de l’histogramme en rouge. Augmenter la taille du pas de
l’histogramme à 20.
4. Ajouter la densité du vecteur de point vec à l’histogramme (Indice : lines(), density(). Que
remarquez-vous ?
5. Afin de mieux apprehender la distribution des données, il est possible d’afficher plusieurs graphiques sur
une même grille. L’objectif de cette partie est d’afficher le scatterplot de la question 1, et au dessus et
sur la droite, les histogrammes des variables “eruption” et “waiting”, respectivement. Pour cela, nous
utiliserons la fonction layout().
5.1 Créer la matrice suivante :
layMat = matrix(c(2,0,1,3), ncol=2, byrow=TRUE)
layMat
## [,1] [,2]
## [1,] 2 0
## [2,] 1 3
Cette matrice permettra à la fonction layout d’afficher les prochains plot :
• en bas à gauche
• en haut à gauche
• en bas à droite
(n.b : le chiffre 0 indique qu’aucun plot ne pourra être affiché dans cette zone)
5.2 Utiliser la fonction layout et la matrice layMat pour créer une grille d’affichage ayant les proportions
suivantes, puis afficher le résultats (indice : layout.show() ) :
• première colonne : 70% de la largeur totale
• deuxième colonne : 30% de la largeur totale
• première ligne : 30% de la largeur totale
• deuxième ligne : 70% de la largeur totale
5.3 Afficher sur ce layout les 3 graphiques suivants :
• le scatter plot de la question 1
• l’histogramme de la variable “eruption”
• l’histogramme de la variable “waiting” (indice : pensez à mettre l’hitogramme à l’horizontal)
#1
data(faithful)
?faithful
plot(faithful$waiting, faithful$eruptions)
13
abline(v=63, col="red")
#2
vec = rnorm(100000, mean = mean(faithful$eruptions), sd = sd(faithful$eruptions))
#3
hist(faithful$eruptions, freq = FALSE, main = "Histogramme de la durée des eruptions", xlab = "Durée de
#4
lines(density(vec))
#5
#5.1
layMat = matrix(c(2,0,1,3), ncol=2, byrow=TRUE)
#5.2
layout(layMat, widths=c(0.7, 0.3), heights=c(0.3, 0.7 ))
layout.show(n=3)
## scatter plot
plot(faithful, xlim=range(faithful$eruptions), ylim=range(faithful$waiting))
xhist = hist(faithful$eruptions, plot=FALSE, breaks=20)
yhist = hist(faithful$waiting , plot=FALSE, breaks=20)
barplot(xhist$density, axes=FALSE, space=0)
barplot(yhist$density, axes=FALSE, space=0, horiz=TRUE)
Un ami vous propose le jeu suivant. On lance un dé. Si le résultat est 5 ou 6, on gagne 3e, si le résultat est 4
on gagne 1e et si c’est 3 ou moins on perd 2.5e. Avant d’accepter la partie, vous essayez de simuler ce jeu,
pour voir si vous avez des chances de vous enrichir.
1. Créer une fonction simul qui prend comme argument un entier compris entre 1 et 6, et qui retourne la
somme correspondante.
2. Créer un vecteur tirage, simulant le résultat de 1000 tirages de dés.
3. Afficher sur un graphique la simulation du jeu.
Conclusion ?
#1
simul = function(i){
res = NULL
if (i <= 6 && i >= 1){
res = switch(i, -2.5, -2.5, -2.5, 1, 3, 3)
}
else {
warning("Un tirage de dès en peut donner qu'un chiffre entre 1 et 6")
}
return(res)
}
#2
tirage = sample(x = c(1:6),size = 1000, replace = TRUE )
14
#3
resultat = sapply(tirage, simul)
gain = cumsum(resultat)
plot(gain)
R contient de nombreux packages nous permettant de faire des représentations graphiques de toutes sortes.
Certains packages permettent de faire des représentations spatiales (rgdal, sp, rgeos,cartography). Connu
comme une boite à outil dédiée à la cartographie thématique, le package cartography est développé au sein
de l’UMS RIATE (CNRS, CGET, Université Paris Diderot) par Nicolas Lambert et Timothée Giraud.
Commencez par installer le package cartograpgy disponible sur le CRAN (via l’utilitaire RStudio ou en
ligne de commande).
Nous allons construire une carte dont l’objectif sera de montrer le nombre de fois où 007 s’est rendu dans
chaque pays.
Pour cela, télécharger les données disponibles à l’adresse suivante : http://wukan.ums-riate.fr/bond/bondfiles.
RData.
Nous avons chargé 2 objets :
• Le data frame BondVisits contient 2 colonnes, l’identifiant des pays (ISO2) et le nombre de visites (n).
• La liste WorldCountries : cette liste est une SpatialPolygonsDataFrame (spdf) contenant la carte de
tous les pays du monde.
1. Afficher la carte du monde grâce à la fonction plot, qui prend en argument des données au format
spdf, avec l’arrière plan en gris. On voit que les marges de la figures sont trop grandes. Modifiez les
pour maximiser l’espace pris par la map monde. Redessinez la map monde. Indice par() option mar
2. Ajouter les cercles proportionnels correspondant aux nombres de visites dans chaque pays de 007, avec
la couleur de votre choix et des bords blanc. Modifier le titre de la légende de “n” à “Nombres de
visites”.
3. On veut à présent représenter le nombres de visites par des couches de couleurs différentes plutôt que
par des symboles proportionnels. Quelle fonction doit-on utiliser ? Appliquer la fonction aux données.
Le résultat obtenu vous parait-il correct ?
4. Regarder le contenu de l’objet WorldCountries@data. Construisez un nouveau dataframe contenant
tous les pays et les nombres de visites (NA ou 0 si inconnu). Réessayez de créer le graphique de la
question précédente. Indice : pour créer le nouveau dataframe, la fonction merge peut vous être utile
library(cartography)
load((url("http://wukan.ums-riate.fr/bond/bondfiles.RData")))
head(BondVisits)
plot(WorldCountries, bg="gray")
par(mar = c(0,0,1.2,0))
plot(WorldCountries, bg="gray")
propSymbolsLayer(spdf = WorldCountries, df = BondVisits, var="n", border="white", col="magenta3", legend
15
Exercice 24 : Profil CGH
Les technologies de génomique permettent de détecter des abérrations au niveau de notre génome (CNA
- Copy Number Alteration) : duplication, remaniement, translocation, perte, etc . . . En cancérologie, le
génome des tumeurs est souvent anormal (voir la figure “Profil CGH”).
Cet exercice a pour objectif de reconstruire ce profil à partir du package “chromosomes” (développé par
B. Job, Gustave Roussy) et du jeu de données A01.ASPCF, issu de l’analyse par des microarrays du type
“Oncoscan” (Affymetrix) de la tumeur d’un patient.
1. Installer le package ‘chromosomes_1.0-0.tgz’ (ce fichier est récupérable sur le site du TP). Charger le
package avec la commande library(); Enfin, charger le dataset hg19. Ceci importe dans votre session
R une variable nommée cs (chromosome structure) décrivant les positions du génome humaine (version
hg19).
a. Quelle est la classe de la variable cs ?
b. Combien le génome contient-il de chromosomes ? (Indice : parcourir l’obet cs avec la fonction
str )
c. Quelle est la taille du génome humain (dans sa version hg19) ?
2. Charger le fichier A01.ascat.ASPCF.RDS dans la variable cgh
a. Quelle est la classe de la variable cgh ?
b. Combien d’éléments contient cette variable ?
c. Quelle est le genre du patient à qui correspond le profil ?
3. Construction du profil CNA
a. Construction des vecteurs de points à afficher depuis la variable cgh :
• Créer le vecteur tumor_lr à partir de la variable cgh
• Créer le vecteur x_snp contenant les positions génomique des points de mesure
• Créer le vecteur x_chr contenant les nom des chromosomes auxquels appartiennent les points
de mesure
• Créer le vecteur all_chr contenant une seule occurrence de ces noms de chromosomes
b. En utilisant la variable cs, construisez le vecteur chr_length, contenant les longueurs des chro-
mosomes. Utiliser la fonction names et la variable cs pour nommer tous les éléments du vecteur
16
chr_length.
c. Convertir les positions relatives au chromosome du vecteur x_snp en position absolue sur le génome
(vecteur x_snp_abs)
d. Afin d’afficher une version lissée du signal mesuré, calculer la “running médiane” (Indice : fonction
runmed ) à partir du vecteur l2r_tumor
e. A partir de ces vecteurs, essayez de reproduire l’image suivante.
Indice : les lignes vertes correspondent à la moyenne des valeurs absolues des différences mesurées entre deux
sondes
#1
install.packages("chromosomes_1.0-0.tar.gz", repos = NULL, type = "source")
library("chromosomes")
data(hg19)
#1.1
class(cs)
#1.2
str(cs)
length(cs$chromosomes$chrom)
#1.3
str(cs)
cs$genome.length
#2
cgh = readRDS(file = "data/A01.ascat.ASPCF.RDS")
#2.1
class(cgh)
#2.2
length(cgh)
#2.3
cgh$gender
#3.1
y_tumor_l2r = cgh$Tumor_LogR[,1]
x_snp = as.numeric(as.vector(cgh$SNPpos$pos))
x_chr = as.vector(cgh$SNPpos$chrs)
all_chr = unique(x_chr)
17
#3.2
chr_length = cs$chromosomes$chr.length.toadd
chr_names = cs$chromosomes$chrN
names(chr_length) = chr_names
#3.3
x_snp_abs = x_snp
for (i in all_chr){
idx = which(x_chr == i)
valtoadd = chr_length[tmp.chr]
#3.4
l2r_runmed = runmed(y_tumor_l2r , k = 301)
#3.5
plot(x_snp_abs, y_tumor_l2r, ylim = c(-2, 2),col = "gray", pch = ".", ylab = "Log2R", xlab = "", axes =
axis(2)
points(x_snp_abs, l2r_runmed, col="blue", pch = ".")
abline(h = 0, lty = 2, col = "red")
abline(v = c(0,cs$chromosomes$chr.length.sum), lty = 2, col = "black")
box(lwd = 2)
tmp = mean(abs(diff(y_tumor_l2r)))
abline(h = c(-tmp, tmp), lty = 2, col = "darkgreen")
18