Vai al contenuto principale

SQLite in R

In questo tutorial imparerai a usare SQLite, un sistema di gestione di database relazionali (RDBMS) estremamente leggero, in R.
Aggiornato 29 set 2026  · 12 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Come accennato alla fine del mio tutorial precedente, Guida per principianti a SQLite, i database SQLite danno il meglio insieme a R e Python. Finora su DataCamp hai visto come lavorare con database SQLite da Python (vedi il tutorial SQLite in Python di Sayak Paul per imparare a manipolare database SQLite tramite il pacchetto sqlite3 in Python). In questo tutorial, invece, ci concentreremo su come usare i database SQLite in R con il pacchetto RSQLite.

Vedremo le basi per svolgere attività essenziali come inviare query a un database SQLite o creare tabelle con RSQLite. Inoltre, tratterò come usare query parametrizzate e operazioni come INSERT o DELETE che non restituiscono risultati tabellari.

Creare database e tabelle

Il primo passo, come avrai intuito, è creare un database. RSQLite può creare database SQLite transitori in memoria, proprio come quando apri la riga di comando di SQLite. Tuttavia, di solito non è ciò che vuoi, quindi creiamo un vero database per il dataset mtcars usando la funzione dbConnect(), che accetta i seguenti argomenti:

  • drv: Un driver di database
  • path: Il percorso di un database SQLite. Se ne stai creando uno nuovo, assegnagli semplicemente un nome a tua scelta come faccio qui sotto. Se vuoi lavorare con un database transitorio in memoria, puoi omettere l'argomento path o digitare ":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")
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

Una volta creato il database e preparati i dati, puoi creare una tabella all'interno del database usando la funzione dbWriteTable(). Questa funzione può accettare molti argomenti ma, per ora, concentriamoci sui seguenti:

  • conn: La connessione al tuo database SQLite
  • name: Il nome che vuoi assegnare alla tua tabella
  • value: I dati che vuoi inserire. Dovrebbero essere un data frame R o un oggetto convertibile in un data frame R.

Dopodiché, puoi usare la funzione dbListTables() passando la connessione al database SQLite come argomento per verificare di aver creato correttamente la tabella.

# 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)

'cars_data'

Una funzionalità estremamente utile quando si creano tabelle con RSQLite è la possibilità di aggiungere altri dati a una tabella esistente usando un ciclo, nel caso tu abbia diversi data frame, impostando l'argomento opzionale append = TRUE dentro dbWriteTable(). Per esempio, creiamo una nuova tabella di prova con alcune auto e i produttori aggiungendo due data frame diversi:

# 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 list
for(k in 1:length(dfList)){
    dbWriteTable(conn,"Cars_and_Makes", dfList[[k]], append = TRUE)
}
# List all the Tables
dbListTables(conn)
  1. 'Cars_and_Makes'
  2. 'cars_data'

Verifichiamo ora che tutti i dati siano nella nuova tabella:

dbGetQuery(conn, "SELECT * FROM Cars_and_Makes")
car make
Camaro Chevrolet
California Ferrari
Mustang Ford
Explorer Ford
Corolla Toyota
Lancer Mitsubishi
Sportage Kia
XE Jaguar

Eseguire query SQL

Come hai visto sopra, è possibile eseguire query SQL valide tramite RSQLite usando la funzione dbGetQuery(), che ha i seguenti argomenti:

  • conn: La connessione al database SQLite
  • query: La query SQL da eseguire come stringa

Per mostrare ulteriormente la capacità di eseguire query SQL con RSQLite, vediamo altri esempi di query sulla tabella cars_data:

Nota: È importante ricordare che, con RSQLite, puoi eseguire qualsiasi query valida per un database SQLite, da semplici SELECT a JOIN (eccetto RIGHT OUTER JOIN e FULL OUTER JOIN, che non sono consentiti in SQLite).

# Gather the first 10 rows in the cars_data table
dbGetQuery(conn, "SELECT * FROM cars_data LIMIT 10")
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")
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)")
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")
cyl average_hp average_mpg
4 82.63636 26.66364
6 122.28571 19.74286
8 209.21429 15.10000

Per salvare i risultati delle tue query in un data frame su cui fare ulteriori operazioni in R, è sufficiente assegnare il risultato della query a una variabile.

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)
cyl average_hp
4 82.63636
6 122.28571
8 209.21429

'data.frame'

Inserire variabili nelle query (query parametrizzate)

Uno dei maggiori vantaggi di lavorare con database SQLite da R è la possibilità di usare query parametrizzate. Cioè, la possibilità di prendere variabili disponibili nel tuo workspace R e usarle per interrogare il tuo database SQLite. Ecco un esempio di come usare una variabile dentro una query 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
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

Come vedi, l'unica differenza tra inviare una query normale e una parametrizzata sta nel valore segnaposto nella query (>= ?) e nell'argomento params di dbGetQuery(), che accetta una lista o un vettore con i valori da assegnare ai segnaposto (in questo caso abbiamo un vettore contenente le variabili mpg e cyl).

E cosa succede quando vuoi eseguire una query diversa? Nell'esempio sopra, come vedi, ho praticamente scritto la query a mano. Permette solo l'inserimento dei valori di mpg e cyl, e la query recupererà solo le auto con mpg e cyl maggiori o uguali. Tuttavia, potrebbero esserci situazioni in cui vuoi essere più flessibile. Cosa succede se un utente vuole vedere anche le auto con cavalli e peso maggiori o uguali a un certo valore? Con la query sopra dovresti tornare indietro e riscriverla, ma potresti scrivere una funzione che renda superfluo quel passaggio. Eccone una:

# 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 query
    for(k in 1: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 placeholder
        if(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
[1] "SELECT car_names, mpg, hp, wt FROM cars_data  WHERE  mpg  >= ?  AND  hp  >= ? AND  wt  >= ?"
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 funzione sopra è basilare, ma mostra come sia possibile scrivere codice R che genera query SQL eseguibili su un database SQLite. Ti invito a esplorare se questo caso d’uso ti interessa. La funzione può essere migliorata in diversi modi, a partire dall’eliminazione dell’assunzione che l’utente voglia vedere solo valori maggiori o uguali a quelli inseriti.

Istruzioni che non restituiscono risultati tabellari

A volte potresti voler eseguire query SQL che non restituiscono necessariamente dati tabellari. Esempi di queste operazioni sono l'inserimento, l'aggiornamento o l'eliminazione di record. Per questo possiamo usare la funzione dbExecute(), che accetta come argomenti una connessione a un database SQLite e una query SQL. Ecco un paio di esempi:

# 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")
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

Ora proviamo a reinserire i dati della 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")

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

Come puoi vedere, l'ultima riga di codice ha aggiunto la Mazda RX4 alla fine della tabella. Quando hai finito di lavorare con il tuo database SQLite in R, è importante chiamare la funzione dbDisconnect(). Questo assicura il rilascio delle risorse utilizzate dalla connessione al database, il che è sempre una buona pratica.

# Close the database connection to CarsDB
dbDisconnect(conn)

Conclusione

In questo tutorial abbiamo visto le funzioni essenziali per manipolare database SQLite in R con RSQLite. Se usati correttamente, i database SQLite sono uno strumento incredibilmente utile quando li integri nei tuoi script R. Un esempio della potenza dell'intersezione tra R e SQLite si vede nelle query parametrizzate, che potresti usare se devi interrogare un database per mostrare informazioni basate sull'input dell'utente in un'app R Shiny. Un altro possibile caso d'uso delle query parametrizzate sono gli assistenti virtuali o i chatbot. Se vuoi saperne di più, ti invito a dare un'occhiata al corso di DataCamp Building Chatbots with Python.

Scrivere tabelle SQLite aggiungendo data frame può essere altrettanto potente. Come ho notato nel tutorial Guida per principianti a SQLite, questa funzionalità mi ha permesso di completare un progetto di analisi di reti sociali aggiungendo alla tabella, man mano che li raccoglievo, i follower di vari utenti Twitter di interesse. Ho usato un database SQLite per risparmiare tempo ed evitare di dover ricominciare da zero in caso di blackout o aggiornamento di Windows che avesse spento forzatamente il computer. Se fosse successo qualcosa del genere, tutto ciò che avrei dovuto fare sarebbe stato riprendere a raccogliere i follower dall'utente successivo all'ultimo presente nel database. Per dare un'idea, il tempo di calcolo per raccogliere i follower di tutti gli utenti Twitter di interesse è stato di quasi 4 settimane a causa dei limiti di frequenza dell'API di Twitter. Quindi, dover ripartire da zero per un blackout o un aggiornamento di Windows sarebbe stato molto sgradito.

Come sempre, ti invito a continuare a imparare sui database SQLite e su come interagirci tramite R. Ti consiglio caldamente di approfondire e controllare i tutorial precedenti che ne trattano l'uso con Python e la riga di comando, che possono aiutarti a diventare un vero mago di SQLite. Continua a imparare: il cielo è il limite!

Argomenti
R
Data Science
SQL

Corsi R

Corso

Introduzione a R

4 ore
3.1M
Impara le basi dell'analisi dei dati in R, compresi vettori, liste e data frame, e fai pratica con R con set di dati reali.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Mostra AltroMostra Altro