2017-05-14 3 views
4

R로 생성 한 벡터를 sqlite 테이블에 새 열로 추가하려고합니다. 이를 위해 dplyr (dbplyr 패키지와 함께 가장 최근의 개발자 버전을이 게시물 here에 따라 설치했습니다.) 내가 뭘하려 :sqlite 데이터베이스에 열 추가

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 

이것을 달성하는 쉬운 방법은 무엇입니까 (반드시 dplyr 포함)?

+0

dplyr는 입력 데이터가 수정되지 않도록 설계되었습니다. 그러나 기존 테이블/데이터 프레임과'mutate()'변환을 기반으로 새로운 테이블을 생성 할 수 있습니다. – krlmlr

답변

3

dyplr으로 이것을 수행하는 방법을 모르지만 직접 RSQLite으로 처리 할 수 ​​있습니다. 문제는 실질적으로 RSQLite과 같지 않지만 사실은 목록을 mutate에 전달하는 방법을 알지 못합니다. 코드에서 다음과 같이 작동합니다.

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

어쨌든, 저의 대안입니다. 장난감 프레임 cars을 만들었습니다.

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

내가 연결을 열고 실제로 테이블을 생성,

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

가 새 열을 추가하고 확인

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> 

그리고 당신은 새로운 열을 업데이트 할 수 있지만, 까다로운 유일한 당신이 where 성명서를 제출해야한다는 것입니다.이 경우 나는 올해를 사용합니다.

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 

는 고유 인덱스로, 당신은 항상 rownames(cars) 사용할 수 있지만 당신은 당신의 dataframe에서 다음 테이블의 열로 추가해야합니다. @krlmlr에 의해 제안 후

편집 : 실제로 훨씬 더 대신 dbGetPreparedQuery되지 않는의 dbExecute를 사용하여, 의견

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

편집 :하지만 경우에도, 몇 일 전에 이것에 대해 생각하지 않았다 SQLite이고 rowid을 사용할 수 있습니다. 나는 이것을 테스트했고 작동합니다.

dbExecute(dbcon, "UPDATE cars SET new_col = :new_col where rowid = :id", 
      params=data.frame(new_col=new_values, 
          id=rownames(cars))) 

테이블의 rowid가 rownames와 동일한 지 반드시 확인해야합니다. 어쨌든 당신은 항상 다음과 같은 rowid를 얻을 수 있습니다 :

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()'는 더 이상 사용되지 않습니다. 대신'dbExecute (..., params = data.frame())'를 사용할 수 있어야합니다. – krlmlr

+0

감사합니다. @krlmlr! – lrnzcig

+0

답해 주셔서 감사합니다. 솔루션에 문제가 하나 있습니다. 유일한 값을 가진 데이터베이스 테이블의 유일한 필드는 거의'rownames (df)'에 해당하는 id입니다. 차이점은 다른 데이터 유형입니다. 데이터베이스에서 타입은'ident'이고 R에서는'character'입니다. 또한 숫자로 시도했지만 둘 다 작동하지 않습니다. 어떻게 해결할 수 있습니까? – Alex

관련 문제