2017-05-14 4 views
4

Ich versuche, einen Vektor, den ich in R generiert, zu einer SQLite-Tabelle als eine neue Spalte hinzuzufügen. Dazu wollte ich dplyr verwenden (Ich habe die neueste Entwicklungsversion zusammen mit dem dbplyr Paket gemäß diesem Beitrag here installiert). Was ich versuchte:Spalte zu SQLite-Datenbank hinzufügen

library(dplyr) 
library(DBI) 

#creating initial database and table 
dbcon  <- dbConnect(RSQLite::SQLite(), "cars.db") 
dbWriteTable(dbcon, name = "cars", value = cars) 
cars_tbl <- dplyr::tbl(dbcon, "cars") 

#new values which I want to add as a new column 
new_values <- sample(c("A","B","C"), nrow(cars), replace = TRUE) 

#attempt to add new values as column to the table in the database 
cars_tbl %>% mutate(new_col = new_values) #not working 

Was ist eine einfache Möglichkeit, dies zu erreichen (nicht unbedingt mit dplyr)?

+0

dplyr ist so konzipiert, Änderungen an den Eingangsdaten zu vermeiden. Sie können jedoch eine neue Tabelle erstellen, die auf einer vorhandenen Tabelle/einem Datenrahmen und einer 'mutate()' - Umwandlung basiert. – krlmlr

Antwort

3

Nicht bewusst, eine Möglichkeit, dies mit dyplr zu tun, aber Sie können es mit RSQLite direkt tun. Das Problem ist nicht wirklich mit RSQLite, aber die Tatsache, dass ich nicht weiß, wie man eine Liste an mutate übergeben. Beachten Sie, dass in Ihrem Code etwas wie dieses funktioniert:

cars_tbl %>% mutate(new_col = another_column/3.14) 

Wie auch immer, meine Alternative. Ich habe ein Spielzeug cars Datenrahmen erstellt.

cars <- data.frame(year=c(1999, 2007, 2009, 2017), model=c("Ford", "Toyota", "Toyota", "BMW")) 

I Verbindung öffnen und tatsächlich die Tabelle erstellen,

dbcon <- dbConnect(RSQLite::SQLite(), "cars.db") 
dbWriteTable(dbcon, name = "cars", value = cars) 

die neue Spalte hinzufügen und überprüfen,

dbGetQuery(dbcon, "ALTER TABLE cars ADD COLUMN new_col TEXT") 
dbGetQuery(dbcon, "SELECT * FROM cars") 
    year model new_col 
1 1999 Ford <NA> 
2 2007 Toyota <NA> 
3 2009 Toyota <NA> 
4 2017 BMW <NA> 

Und dann können Sie die neue Spalte aktualisieren, aber die einzige knifflige Sache ist, dass Sie eine where Aussage zur Verfügung stellen müssen, in diesem Fall benutze ich das Jahr.

new_values <- sample(c("A","B","C"), nrow(cars), replace = TRUE) 
new_values 
[1] "C" "B" "B" "B" 

dbGetPreparedQuery(dbcon, "UPDATE cars SET new_col = ? where year=?", 
        bind.data=data.frame(new_col=new_values, 
             year=cars$year)) 

dbGetQuery(dbcon, "SELECT * FROM cars") 
    year model new_col 
1 1999 Ford  C 
2 2007 Toyota  B 
3 2009 Toyota  B 
4 2017 BMW  B 

Als eindeutiger Index, Sie immer rownames(cars) verwenden könnten, aber man würde es als eine Spalte in dem Datenrahmen hinzufügen müssen und dann in der Tabelle.

EDIT nach Vorschlag von @krlmlr: in der Tat viel besser dbExecute statt dbGetPreparedQuery veraltet verwenden,

dbExecute(dbcon, "UPDATE cars SET new_col = :new_col where year = :year", 
      params=data.frame(new_col=new_values, 
          year=cars$year)) 

EDIT nach Kommentare: Ich glaube nicht, vor ein paar Tagen darüber, aber selbst wenn Es ist ein SQLite Sie können die rowid verwenden. Ich habe das getestet und es funktioniert.

Obwohl Sie sicherstellen müssen, dass die Rowiden in der Tabelle die gleichen wie Ihre rownames sind. Auf jeden Fall können Sie immer Ihre Rowid ist wie diese:

dbGetQuery(dbcon, "SELECT rowid, * FROM cars") 
    rowid year model new_col 
1  1 1999 Ford  C 
2  2 2007 Toyota  B 
3  3 2009 Toyota  B 
4  4 2017 BMW  B 
+0

'dbGetPreparedQuery()' ist veraltet, Sie sollten stattdessen 'dbExecute (..., params = data.frame())' 'verwenden können. – krlmlr

+0

Danke @krmlnr! – lrnzcig

+0

Danke für die Antwort. Ich habe ein Problem mit Ihrer Lösung. Das einzige Feld in der Datenbanktabelle mit eindeutigen Werten ist die ID, die fast "roownames (df)" entspricht. Der Unterschied ist ein anderer Datentyp. In der Datenbank ist der Typ "ident" und in R ist es "character". Ich habe es auch mit 'numeric' versucht, aber beides funktioniert nicht. Wie kann ich das beheben? – Alex

Verwandte Themen