Comme mentionné à la fin de mon précédent tutoriel, Beginners Guide to SQLite, les bases de données SQLite sont particulièrement puissantes lorsqu'elles sont utilisées avec R et Python. Jusqu'ici sur DataCamp, vous avez vu comment interagir avec des bases SQLite depuis Python (consultez le tutoriel SQLite in Python de Sayak Paul pour apprendre à manipuler des bases SQLite via le package sqlite3 en Python). Dans ce tutoriel, nous allons toutefois nous concentrer sur l'utilisation de SQLite dans R avec le package RSQLite.
Nous passerons en revue les bases pour réaliser des opérations essentielles comme envoyer des requêtes à une base SQLite ou créer des tables via RSQLite. Nous verrons également comment utiliser des requêtes paramétrées et des opérations comme INSERT ou DELETE qui ne renvoient pas de résultats tabulaires.
Créer des bases de données et des tables
La première étape, vous vous en doutez, consiste à créer une base. RSQLite peut créer des bases SQLite éphémères en mémoire, comme lorsque vous ouvrez la ligne de commande SQLite. Ce n'est toutefois pas toujours ce que vous souhaitez. Créons donc une base dédiée au jeu de données mtcars avec la fonction dbConnect(), qui prend les arguments suivants :
drv : un pilote de base de données
path : le chemin de la base SQLite. Si vous en créez une nouvelle, donnez-lui simplement un nom, comme ci-dessous. Si vous voulez travailler avec une base transitoire en mémoire, vous pouvez omettre l'argument path ou saisir ":memory:".
# Load the RSQLite Library
library(RSQLite)# Load the mtcars as an R data frame put the row names as a column, and print the header.
data("mtcars")
mtcars$car_names <- rownames(mtcars)
rownames(mtcars)<- c()
head(mtcars)# Create a connection to our new database, CarsDB.db# you can check that the .db file has been created on your working directory
conn <- dbConnect(RSQLite::SQLite(),"CarsDB.db")Propulsé par
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
car_names
21.0
6
160
110
3.90
2.620
16.46
0
1
4
4
Mazda RX4
21.0
6
160
110
3.90
2.875
17.02
0
1
4
4
Mazda RX4 Wag
22.8
4
108
93
3.85
2.320
18.61
1
1
4
1
Datsun 710
21.4
6
258
110
3.08
3.215
19.44
1
0
3
1
Hornet 4 Drive
18.7
8
360
175
3.15
3.440
17.02
0
0
3
2
Hornet Sportabout
18.1
6
225
105
2.76
3.460
20.22
1
0
3
1
Valiant
Une fois la base créée et vos données prêtes, vous pouvez créer une table dans la base avec la fonction dbWriteTable(). Cette fonction accepte de nombreux arguments, mais concentrons-nous sur les suivants :
conn : la connexion à votre base SQLite
name : le nom à donner à votre table
value : les données à insérer. Il doit s'agir d'un data frame R ou d'un objet convertible en data frame.
Ensuite, vous pouvez utiliser la fonction dbListTables() avec la connexion SQLite en argument pour vérifier que la table a bien été créée.
# Write the mtcars dataset into a table names mtcars_data
dbWriteTable(conn,"cars_data", mtcars)# List all the tables available in the database
dbListTables(conn)Propulsé par
'cars_data'
Une fonctionnalité très utile lors de la création de tables avec RSQLite est la possibilité d'ajouter des données à une table existante via une boucle si vous avez plusieurs data frames, en définissant l'argument optionnel append = TRUE dans dbWriteTable(). Par exemple, créons une table jouet listant quelques modèles et constructeurs en concaténant deux data frames :
# Create toy data frames
car <- c('Camaro','California','Mustang','Explorer')
make <- c('Chevrolet','Ferrari','Ford','Ford')
df1 <- data.frame(car,make)
car <- c('Corolla','Lancer','Sportage','XE')
make <- c('Toyota','Mitsubishi','Kia','Jaguar')
df2 <- data.frame(car,make)# Add them to a list
dfList <- list(df1,df2)# Write a table by appending the data frames inside the listfor(k in1:length(dfList)){
dbWriteTable(conn,"Cars_and_Makes", dfList[[k]], append =TRUE)}# List all the Tables
dbListTables(conn)Propulsé par
'Cars_and_Makes'
'cars_data'
Vérifions maintenant que toutes les données figurent bien dans la nouvelle table :
dbGetQuery(conn,"SELECT * FROM Cars_and_Makes")Propulsé par
car
make
Camaro
Chevrolet
California
Ferrari
Mustang
Ford
Explorer
Ford
Corolla
Toyota
Lancer
Mitsubishi
Sportage
Kia
XE
Jaguar
Exécuter des requêtes SQL
Comme vous l'avez vu ci-dessus, il est possible d'exécuter des requêtes SQL valides via RSQLite grâce à la fonction dbGetQuery(), qui prend les arguments suivants :
conn : la connexion à la base SQLite
query : la requête SQL à exécuter sous forme de chaîne
Pour illustrer davantage l'exécution de requêtes SQL avec RSQLite, passons quelques exemples supplémentaires sur la table cars_data :
Remarque : gardez à l'esprit qu'avec RSQLite, vous pouvez exécuter toute requête valide pour SQLite, des simples requêtes SELECT aux JOINS (à l'exception des RIGHT OUTER JOIN et FULL OUTER JOIN, non pris en charge par SQLite).
# Gather the first 10 rows in the cars_data table
dbGetQuery(conn,"SELECT * FROM cars_data LIMIT 10")Propulsé par
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
car_names
21.0
6
160.0
110
3.90
2.620
16.46
0
1
4
4
Mazda RX4
21.0
6
160.0
110
3.90
2.875
17.02
0
1
4
4
Mazda RX4 Wag
22.8
4
108.0
93
3.85
2.320
18.61
1
1
4
1
Datsun 710
21.4
6
258.0
110
3.08
3.215
19.44
1
0
3
1
Hornet 4 Drive
18.7
8
360.0
175
3.15
3.440
17.02
0
0
3
2
Hornet Sportabout
18.1
6
225.0
105
2.76
3.460
20.22
1
0
3
1
Valiant
14.3
8
360.0
245
3.21
3.570
15.84
0
0
3
4
Duster 360
24.4
4
146.7
62
3.69
3.190
20.00
1
0
4
2
Merc 240D
22.8
4
140.8
95
3.92
3.150
22.90
1
0
4
2
Merc 230
19.2
6
167.6
123
3.92
3.440
18.30
1
0
4
4
Merc 280
# Get the car names and horsepower of the cars with 8 cylinders
dbGetQuery(conn,"SELECT car_names, hp, cyl FROM cars_data
WHERE cyl =8")Propulsé par
car_names
hp
cyl
Hornet Sportabout
175
8
Duster 360
245
8
Merc 450SE
180
8
Merc 450SL
180
8
Merc 450SLC
180
8
Cadillac Fleetwood
205
8
Lincoln Continental
215
8
Chrysler Imperial
230
8
Dodge Challenger
150
8
AMC Javelin
150
8
Camaro Z28
245
8
Pontiac Firebird
175
8
Ford Pantera L
264
8
Maserati Bora
335
8
# Get the car names and horsepower starting with M that have 6 or 8 cylinders
dbGetQuery(conn,"SELECT car_names, hp, cyl FROM cars_data
WHERE car_names LIKE 'M%' AND cyl IN (6,8)")Propulsé par
car_names
hp
cyl
Mazda RX4
110
6
Mazda RX4 Wag
110
6
Merc 280
123
6
Merc 280C
123
6
Merc 450SE
180
8
Merc 450SL
180
8
Merc 450SLC
180
8
Maserati Bora
335
8
# Get the average horsepower and mpg by number of cylinder groups
dbGetQuery(conn,"SELECT cyl, AVG(hp) AS 'average_hp', AVG(mpg) AS 'average_mpg' FROM cars_data
GROUP BY cyl
ORDER BY average_hp")Propulsé par
cyl
average_hp
average_mpg
4
82.63636
26.66364
6
122.28571
19.74286
8
209.21429
15.10000
Pour stocker les résultats de vos requêtes et poursuivre l'analyse dans R sous forme de data frame, il suffit d'assigner le résultat à une variable.
avg_HpCyl <- dbGetQuery(conn,"SELECT cyl, AVG(hp) AS 'average_hp'FROM cars_data
GROUP BY cyl
ORDER BY average_hp")
avg_HpCyl
class(avg_HpCyl)Propulsé par
cyl
average_hp
4
82.63636
6
122.28571
8
209.21429
'data.frame'
Insérer des variables dans des requêtes (requêtes paramétrées)
L'un des grands avantages d'opérer avec des bases SQLite depuis R est la possibilité d'utiliser des requêtes paramétrées. Autrement dit, exploiter des variables disponibles dans votre espace de travail R pour interroger votre base SQLite. Voici un exemple d'utilisation d'une variable dans une requête SQLite :
# Lets assume that there is some user input that asks us to look only into cars that have over 18 miles per gallon (mpg)# and more than 6 cylinders
mpg <-18
cyl <-6
Result <- dbGetQuery(conn,'SELECT car_names, mpg, cyl FROM cars_data WHERE mpg >= ? AND cyl >= ?', params = c(mpg,cyl))
Result
Propulsé par
car_names
mpg
cyl
Mazda RX4
21.0
6
Mazda RX4 Wag
21.0
6
Hornet 4 Drive
21.4
6
Hornet Sportabout
18.7
8
Valiant
18.1
6
Merc 280
19.2
6
Pontiac Firebird
19.2
8
Ferrari Dino
19.7
6
Comme vous le voyez, la seule différence entre une requête « classique » et une requête paramétrée tient au caractère générique dans la requête (>= ?) et à l'argument params de dbGetQuery(), qui prend une liste ou un vecteur avec les valeurs à attribuer aux espaces réservés (ici un vecteur contenant les variables mpg et cyl).
Que se passe-t-il si vous souhaitez exécuter une autre requête ? Dans l'exemple ci-dessus, la requête est écrite à la main : elle ne prend en compte que des valeurs de mpg et de cyl, et ne renverra que les voitures dont le mpg et le cyl sont supérieurs ou égaux. Mais certaines situations exigent plus de flexibilité. Et si un utilisateur souhaite aussi filtrer sur une puissance et un poids supérieurs ou égaux à une valeur donnée ? Avec la requête précédente, il faudrait la réécrire. Vous pouvez cependant créer une fonction qui vous évite cette étape. En voici une :
# Assemble an example function that takes the SQLite database connection, a base query,# and the parameters you want to use in the WHERE clause as a list
assembleQuery <-function(conn, base, search_parameters){
parameter_names <- names(search_parameters)
partial_queries <-""# Iterate over all the parameters to assemble the queryfor(k in1:length(parameter_names)){
filter_k <- paste(parameter_names[k]," >= ? ")# If there is more than 1 parameter, add an AND statement before the parameter name and placeholderif(k >1){
filter_k <- paste("AND ", parameter_names[k]," >= ?")}
partial_queries <- paste(partial_queries, filter_k)}# Paste all together into a single query using a WHERE statement
final_paste <- paste(base," WHERE", partial_queries)# Print the assembled query to show how it looks like
print(final_paste)# Run the final query. I unlist the values from the search_parameters list into a vector since it is needed# when using various anonymous placeholders (i.e. >= ?)
values <- unlist(search_parameters, use.names =FALSE)
result <- dbGetQuery(conn, final_paste, params = values)# return the executed query
return(result)}
base <-"SELECT car_names, mpg, hp, wt FROM cars_data"
search_parameters <- list("mpg"=16,"hp"=150,"wt"=2.1)
result <- assembleQuery(conn, base, search_parameters)
result
Propulsé par
[1]"SELECT car_names, mpg, hp, wt FROM cars_data WHERE mpg >= ? AND hp >= ? AND wt >= ?"Propulsé par
car_names
mpg
hp
wt
Hornet Sportabout
18.7
175
3.440
Merc 450SE
16.4
180
4.070
Merc 450SL
17.3
180
3.730
Pontiac Firebird
19.2
175
3.845
Ferrari Dino
19.7
175
2.770
La fonction ci-dessus est simple, mais elle illustre comment écrire du code R qui génère des requêtes SQL exécutables sur une base SQLite. Si ce cas d'usage vous intéresse, je vous invite à aller plus loin. Vous pouvez améliorer cette fonction de plusieurs façons, à commencer par lever l'hypothèse selon laquelle l'utilisateur souhaite forcément filtrer sur des valeurs supérieures ou égales à celles saisies.
Instructions qui ne renvoient pas de résultats tabulaires
Parfois, vous voudrez exécuter des requêtes SQL qui ne renvoient pas de données tabulaires. C'est le cas des opérations d'insertion, de mise à jour ou de suppression d'enregistrements. Pour cela, utilisez la fonction dbExecute(), qui prend en arguments une connexion SQLite et une requête SQL. Voici deux exemples :
# Visualize the table before deletion
dbGetQuery(conn,"SELECT * FROM cars_data LIMIT 10")# Delete the column belonging to the Mazda RX4. You will see a 1 as the output.
dbExecute(conn,"DELETE FROM cars_data WHERE car_names = 'Mazda RX4'")# Visualize the new table after deletion
dbGetQuery(conn,"SELECT * FROM cars_data LIMIT 10")Propulsé par
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
car_names
21.0
6
160.0
110
3.90
2.620
16.46
0
1
4
4
Mazda RX4
21.0
6
160.0
110
3.90
2.875
17.02
0
1
4
4
Mazda RX4 Wag
22.8
4
108.0
93
3.85
2.320
18.61
1
1
4
1
Datsun 710
21.4
6
258.0
110
3.08
3.215
19.44
1
0
3
1
Hornet 4 Drive
18.7
8
360.0
175
3.15
3.440
17.02
0
0
3
2
Hornet Sportabout
18.1
6
225.0
105
2.76
3.460
20.22
1
0
3
1
Valiant
14.3
8
360.0
245
3.21
3.570
15.84
0
0
3
4
Duster 360
24.4
4
146.7
62
3.69
3.190
20.00
1
0
4
2
Merc 240D
22.8
4
140.8
95
3.92
3.150
22.90
1
0
4
2
Merc 230
19.2
6
167.6
123
3.92
3.440
18.30
1
0
4
4
Merc 280
1
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
car_names
21.0
6
160.0
110
3.90
2.875
17.02
0
1
4
4
Mazda RX4 Wag
22.8
4
108.0
93
3.85
2.320
18.61
1
1
4
1
Datsun 710
21.4
6
258.0
110
3.08
3.215
19.44
1
0
3
1
Hornet 4 Drive
18.7
8
360.0
175
3.15
3.440
17.02
0
0
3
2
Hornet Sportabout
18.1
6
225.0
105
2.76
3.460
20.22
1
0
3
1
Valiant
14.3
8
360.0
245
3.21
3.570
15.84
0
0
3
4
Duster 360
24.4
4
146.7
62
3.69
3.190
20.00
1
0
4
2
Merc 240D
22.8
4
140.8
95
3.92
3.150
22.90
1
0
4
2
Merc 230
19.2
6
167.6
123
3.92
3.440
18.30
1
0
4
4
Merc 280
17.8
6
167.6
123
3.92
3.440
18.90
1
0
4
4
Merc 280C
Essayons maintenant de réinsérer les données de la Mazda RX4 :
# Insert the data for the Mazda RX4. This will also ouput a 1
dbExecute(conn,"INSERT INTO cars_data VALUES (21.0,6,160.0,110,3.90,2.620,16.46,0,1,4,4,'Mazda RX4')")# See that we re-introduced the Mazda RX4 succesfully at the end
dbGetQuery(conn,"SELECT * FROM cars_data")Propulsé par
1
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
car_names
21.0
6
160.0
110
3.90
2.875
17.02
0
1
4
4
Mazda RX4 Wag
22.8
4
108.0
93
3.85
2.320
18.61
1
1
4
1
Datsun 710
21.4
6
258.0
110
3.08
3.215
19.44
1
0
3
1
Hornet 4 Drive
18.7
8
360.0
175
3.15
3.440
17.02
0
0
3
2
Hornet Sportabout
18.1
6
225.0
105
2.76
3.460
20.22
1
0
3
1
Valiant
14.3
8
360.0
245
3.21
3.570
15.84
0
0
3
4
Duster 360
24.4
4
146.7
62
3.69
3.190
20.00
1
0
4
2
Merc 240D
22.8
4
140.8
95
3.92
3.150
22.90
1
0
4
2
Merc 230
19.2
6
167.6
123
3.92
3.440
18.30
1
0
4
4
Merc 280
17.8
6
167.6
123
3.92
3.440
18.90
1
0
4
4
Merc 280C
16.4
8
275.8
180
3.07
4.070
17.40
0
0
3
3
Merc 450SE
17.3
8
275.8
180
3.07
3.730
17.60
0
0
3
3
Merc 450SL
15.2
8
275.8
180
3.07
3.780
18.00
0
0
3
3
Merc 450SLC
10.4
8
472.0
205
2.93
5.250
17.98
0
0
3
4
Cadillac Fleetwood
10.4
8
460.0
215
3.00
5.424
17.82
0
0
3
4
Lincoln Continental
14.7
8
440.0
230
3.23
5.345
17.42
0
0
3
4
Chrysler Imperial
32.4
4
78.7
66
4.08
2.200
19.47
1
1
4
1
Fiat 128
30.4
4
75.7
52
4.93
1.615
18.52
1
1
4
2
Honda Civic
33.9
4
71.1
65
4.22
1.835
19.90
1
1
4
1
Toyota Corolla
21.5
4
120.1
97
3.70
2.465
20.01
1
0
3
1
Toyota Corona
15.5
8
318.0
150
2.76
3.520
16.87
0
0
3
2
Dodge Challenger
15.2
8
304.0
150
3.15
3.435
17.30
0
0
3
2
AMC Javelin
13.3
8
350.0
245
3.73
3.840
15.41
0
0
3
4
Camaro Z28
19.2
8
400.0
175
3.08
3.845
17.05
0
0
3
2
Pontiac Firebird
27.3
4
79.0
66
4.08
1.935
18.90
1
1
4
1
Fiat X1-9
26.0
4
120.3
91
4.43
2.140
16.70
0
1
5
2
Porsche 914-2
30.4
4
95.1
113
3.77
1.513
16.90
1
1
5
2
Lotus Europa
15.8
8
351.0
264
4.22
3.170
14.50
0
1
5
4
Ford Pantera L
19.7
6
145.0
175
3.62
2.770
15.50
0
1
5
6
Ferrari Dino
15.0
8
301.0
335
3.54
3.570
14.60
0
1
5
8
Maserati Bora
21.4
4
121.0
109
4.11
2.780
18.60
1
1
4
2
Volvo 142E
21.0
6
160.0
110
3.90
2.620
16.46
0
1
4
4
Mazda RX4
Comme vous pouvez le constater, la dernière ligne de code a ajouté la Mazda RX4 à la fin de la table. Une fois votre travail terminé avec la base SQLite dans R, pensez à appeler la fonction dbDisconnect(). Cela permet de libérer les ressources utilisées par la connexion à la base, ce qui est une bonne pratique.
# Close the database connection to CarsDB
dbDisconnect(conn)Propulsé par
Conclusion
Dans ce tutoriel, nous avons couvert les fonctions essentielles pour manipuler des bases SQLite dans R à l'aide de RSQLite. Bien utilisées, les bases SQLite sont un outil extrêmement utile au sein de vos scripts R. La puissance de l'intersection entre R et SQLite apparaît notamment avec les requêtes paramétrées, par exemple pour interroger une base afin d'afficher des informations selon des saisies utilisateur dans une application R Shiny. Autre cas d'usage des requêtes paramétrées : des assistants virtuels ou chatbots. Pour en savoir plus, consultez le cours Building Chatbots with Python de DataCamp.
L'écriture de tables SQLite par ajout successif de data frames peut aussi s'avérer très puissante. Comme je l'ai indiqué dans le tutoriel Beginners Guide to SQLite, cette capacité m'a permis de mener à bien un projet d'analyse de réseau social en ajoutant, au fil de la collecte, les abonnés de plusieurs utilisateurs Twitter d'intérêt dans une table. J'ai utilisé une base SQLite pour gagner du temps et éviter de repartir de zéro en cas de coupure de courant ou de mise à jour Windows entraînant l'arrêt forcé de l'ordinateur. Dans un tel cas, il suffisait de reprendre la collecte à l'utilisateur suivant le dernier enregistré dans la base. Pour situer l'ordre de grandeur, la collecte des abonnés de tous mes utilisateurs d'intérêt a pris près de 4 semaines à cause des limites de l'API Twitter. Repartir de zéro à cause d'un incident aurait été très problématique.
Comme toujours, continuez à explorer les bases SQLite et leurs interactions avec R. Je vous recommande vivement d'approfondir en consultant les précédents tutoriels sur leur utilisation avec Python et la ligne de commande, pour devenir incollable sur SQLite. Continuez à apprendre : tout est possible !
Apprenez l'essentiel de l'architecture d'un entrepôt de données, des composants clés aux meilleures pratiques, pour construire un système de données évolutif et efficace !
Initiez-vous aux structures de données de Python : apprenez-en plus sur les types de données et les structures de données primitives et non primitives, telles que les chaînes de caractères, les listes, les piles, etc.
Gagnez en confiance dans la régression par les MCO en maîtrisant ses fondements théoriques. Découvrez comment réaliser des mises en œuvre simples dans Excel, R et Python.
Poursuivez votre parcours pour devenir un ninja de R en vous familiarisant avec les instructions conditionnelles, les boucles et les fonctions vectorielles.
Comme mentionné à la fin de mon précédent tutoriel, Beginners Guide to SQLite, les bases de données SQLite sont particulièrement puissantes lorsqu'elles sont utilisées avec R et Python. Jusqu'ici sur DataCamp, vous avez vu comment interagir avec des bases SQLite depuis Python (consultez le tutoriel SQLite in Python de Sayak Paul pour apprendre à manipuler des bases SQLite via le package sqlite3 en Python). Dans ce tutoriel, nous allons toutefois nous concentrer sur l'utilisation de SQLite dans R avec le package RSQLite.
Nous passerons en revue les bases pour réaliser des opérations essentielles comme envoyer des requêtes à une base SQLite ou créer des tables via RSQLite. Nous verrons également comment utiliser des requêtes paramétrées et des opérations comme INSERT ou DELETE qui ne renvoient pas de résultats tabulaires.
Créer des bases de données et des tables
La première étape, vous vous en doutez, consiste à créer une base. RSQLite peut créer des bases SQLite éphémères en mémoire, comme lorsque vous ouvrez la ligne de commande SQLite. Ce n'est toutefois pas toujours ce que vous souhaitez. Créons donc une base dédiée au jeu de données mtcars avec la fonction dbConnect(), qui prend les arguments suivants :
Une fois la base créée et vos données prêtes, vous pouvez créer une table dans la base avec la fonction dbWriteTable(). Cette fonction accepte de nombreux arguments, mais concentrons-nous sur les suivants :
Ensuite, vous pouvez utiliser la fonction dbListTables() avec la connexion SQLite en argument pour vérifier que la table a bien été créée.
'cars_data'
Une fonctionnalité très utile lors de la création de tables avec RSQLite est la possibilité d'ajouter des données à une table existante via une boucle si vous avez plusieurs data frames, en définissant l'argument optionnel append = TRUE dans dbWriteTable(). Par exemple, créons une table jouet listant quelques modèles et constructeurs en concaténant deux data frames :
Vérifions maintenant que toutes les données figurent bien dans la nouvelle table :
Exécuter des requêtes SQL
Comme vous l'avez vu ci-dessus, il est possible d'exécuter des requêtes SQL valides via RSQLite grâce à la fonction dbGetQuery(), qui prend les arguments suivants :
Pour illustrer davantage l'exécution de requêtes SQL avec RSQLite, passons quelques exemples supplémentaires sur la table cars_data :
Remarque : gardez à l'esprit qu'avec RSQLite, vous pouvez exécuter toute requête valide pour SQLite, des simples requêtes SELECT aux JOINS (à l'exception des RIGHT OUTER JOIN et FULL OUTER JOIN, non pris en charge par SQLite).
Pour stocker les résultats de vos requêtes et poursuivre l'analyse dans R sous forme de data frame, il suffit d'assigner le résultat à une variable.
'data.frame'
Insérer des variables dans des requêtes (requêtes paramétrées)
L'un des grands avantages d'opérer avec des bases SQLite depuis R est la possibilité d'utiliser des requêtes paramétrées. Autrement dit, exploiter des variables disponibles dans votre espace de travail R pour interroger votre base SQLite. Voici un exemple d'utilisation d'une variable dans une requête SQLite :
Comme vous le voyez, la seule différence entre une requête « classique » et une requête paramétrée tient au caractère générique dans la requête (>= ?) et à l'argument params de dbGetQuery(), qui prend une liste ou un vecteur avec les valeurs à attribuer aux espaces réservés (ici un vecteur contenant les variables mpg et cyl).
Que se passe-t-il si vous souhaitez exécuter une autre requête ? Dans l'exemple ci-dessus, la requête est écrite à la main : elle ne prend en compte que des valeurs de mpg et de cyl, et ne renverra que les voitures dont le mpg et le cyl sont supérieurs ou égaux. Mais certaines situations exigent plus de flexibilité. Et si un utilisateur souhaite aussi filtrer sur une puissance et un poids supérieurs ou égaux à une valeur donnée ? Avec la requête précédente, il faudrait la réécrire. Vous pouvez cependant créer une fonction qui vous évite cette étape. En voici une :
La fonction ci-dessus est simple, mais elle illustre comment écrire du code R qui génère des requêtes SQL exécutables sur une base SQLite. Si ce cas d'usage vous intéresse, je vous invite à aller plus loin. Vous pouvez améliorer cette fonction de plusieurs façons, à commencer par lever l'hypothèse selon laquelle l'utilisateur souhaite forcément filtrer sur des valeurs supérieures ou égales à celles saisies.
Instructions qui ne renvoient pas de résultats tabulaires
Parfois, vous voudrez exécuter des requêtes SQL qui ne renvoient pas de données tabulaires. C'est le cas des opérations d'insertion, de mise à jour ou de suppression d'enregistrements. Pour cela, utilisez la fonction dbExecute(), qui prend en arguments une connexion SQLite et une requête SQL. Voici deux exemples :
1
Essayons maintenant de réinsérer les données de la Mazda RX4 :
1
Comme vous pouvez le constater, la dernière ligne de code a ajouté la Mazda RX4 à la fin de la table. Une fois votre travail terminé avec la base SQLite dans R, pensez à appeler la fonction dbDisconnect(). Cela permet de libérer les ressources utilisées par la connexion à la base, ce qui est une bonne pratique.
Conclusion
Dans ce tutoriel, nous avons couvert les fonctions essentielles pour manipuler des bases SQLite dans R à l'aide de RSQLite. Bien utilisées, les bases SQLite sont un outil extrêmement utile au sein de vos scripts R. La puissance de l'intersection entre R et SQLite apparaît notamment avec les requêtes paramétrées, par exemple pour interroger une base afin d'afficher des informations selon des saisies utilisateur dans une application R Shiny. Autre cas d'usage des requêtes paramétrées : des assistants virtuels ou chatbots. Pour en savoir plus, consultez le cours Building Chatbots with Python de DataCamp.
L'écriture de tables SQLite par ajout successif de data frames peut aussi s'avérer très puissante. Comme je l'ai indiqué dans le tutoriel Beginners Guide to SQLite, cette capacité m'a permis de mener à bien un projet d'analyse de réseau social en ajoutant, au fil de la collecte, les abonnés de plusieurs utilisateurs Twitter d'intérêt dans une table. J'ai utilisé une base SQLite pour gagner du temps et éviter de repartir de zéro en cas de coupure de courant ou de mise à jour Windows entraînant l'arrêt forcé de l'ordinateur. Dans un tel cas, il suffisait de reprendre la collecte à l'utilisateur suivant le dernier enregistré dans la base. Pour situer l'ordre de grandeur, la collecte des abonnés de tous mes utilisateurs d'intérêt a pris près de 4 semaines à cause des limites de l'API Twitter. Repartir de zéro à cause d'un incident aurait été très problématique.
Comme toujours, continuez à explorer les bases SQLite et leurs interactions avec R. Je vous recommande vivement d'approfondir en consultant les précédents tutoriels sur leur utilisation avec Python et la ligne de commande, pour devenir incollable sur SQLite. Continuez à apprendre : tout est possible !