用R连接几个DBF文件

时间:2014-12-03 17:52:56

标签: r merge dataframe data.table

我几乎不擅长R,我一直在尝试合并从dbffiles读取的几个data.tables。

文件的结构如下:

Survey
| ID | ITEMID | ITEMQTY |          DESCCODE | PROVIDERID |
|----|--------|---------|-------------------|------------|
|  1 |      1 |      50 |        sku:247504 |          1 |
|  1 |      2 |       3 | Item discontinued |          1 |
|  1 |      3 |     400 | Item discontinued |          3 |
|  2 |      1 |     500 |      Storage item |          2 |
|  3 |      1 |     500 |    something else |          3 |

Item
| ID |               ITEMNAME | ITEMPRICE |
|----|------------------------|-----------|
|  1 |            Kolashampan |         4 |
|  2 | Arepas by Dr. Colombia |         5 |
|  3 |               Biscotti |         2 |

Provider
| ID |       PROVIDERNAME | LOCATIONID |            PRIMARYCONTACT |
|----|--------------------|------------|---------------------------|
|  1 | Salvadoran Imports |       9056 |             Dra. Castillo |
|  2 |   Rolo Importadora |         46 |              Dra. Coquita |
|  3 |       Il Italianni |         64 | Il Ittalianni call center |

我想要实现的是3个文件的基本内连接,在sql中就是这样:

| ID |          DESCCODE |               ITEMNAME | TOTAMOUNT |       PROVIDERNAME |
|----|-------------------|------------------------|-----------|--------------------|
|  1 | Item discontinued | Arepas by Dr. Colombia |        15 | Salvadoran Imports |
|  1 |        sku:247504 |            Kolashampan |       200 | Salvadoran Imports |
|  1 | Item discontinued |               Biscotti |       800 |       Il Italianni |
|  2 |      Storage item |            Kolashampan |      2000 |   Rolo Importadora |
|  3 |    something else |            Kolashampan |      2000 |       Il Italianni |

获得此查询:

select
    s.id,
    s.descCode,
    i.itemname,
    (i.itemprice*s.itemqty) as totAmount,
    p.providername
from
    survey s,
    item i,
    provider p
where
    s.itemid = i.id
    and s.providerid = p.id
order by s.id

这是我的代码:

library("shapefiles")
library("data.table")
library("reshape2")
survey <- read.dbf( file.choose(), header="true" )
survey$id <- as.factor( survey$numeric )
print(survey$header$num.records)

item <- read.dbf( file.choose(), header="true" )
item$id <- as.factor( item$numeric )
print(item$header$num.records)

provider <- read.dbf( file.choose(), header="true" )
provider$id <- as.factor( provider$numeric )
print(provider$header$num.records)

setDT(survey, giveNames=FALSE, keep.rownames=FALSE)
setkey(survey, survey$id)

setDT(item, giveNames=FALSE, keep.rownames=FALSE)
setkey(item, item$id)

setDT(provider, giveNames=FALSE, keep.rownames=FALSE)
setkey(provider, provider$id)

merge(survey,item,by="itemid")
merge(survey,provider,by="providerid")

write.dbf(survey[, id, desccode, itemname, itemqty*itemprice, provider, with = FALSE], "joinedFile.dbf")

从这里,我遇到的麻烦是:

  • 使用setDT,我收到此错误参数&#39; x&#39;中的所有元素到了#D;&#39;必须长度相同
  • 使用dtSurvey&lt; - as.data.table(调查)它似乎有效,但我有点担心,因为dbf文件会变大。
  • 但是,即使我使用最后两点,我总是会尝试使用setkey时出错: x不是data.table
  • 作为一个额外的问题,合并可以使用 survey [item] 之类的东西完成吗?

非常感谢。

修改

这些是文件的输出输出

调查

structure(list(dbf = structure(list(N_ID_ = structure(c(1L, 1L, 
1L, 2L, 3L), .Label = c("1", "2", "3"), class = "factor"), N_ITEMID_ = structure(c(1L, 
2L, 3L, 1L, 1L), .Label = c("1", "2", "3"), class = "factor"), 
    N_ITEMQTY_ = structure(c(3L, 1L, 2L, 4L, 4L), .Label = c("3", 
    "400", "50", "500"), class = "factor"), N_________ = structure(c(2L, 
    1L, 1L, 4L, 3L), .Label = c("Item discontinued", "sku:247504", 
    "something else", "Storage item"), class = "factor"), N_PROVIDER = structure(c(1L, 
    1L, 3L, 2L, 3L), .Label = c("1", "2", "3"), class = "factor")), .Names = c("N_ID_", 
"N_ITEMID_", "N_ITEMQTY_", "N_________", "N_PROVIDER"), row.names = c(NA, 
-5L), class = "data.frame", data_types = c("C", "C", "C", "C", 
"C")), header = structure(list(file.version = 3L, file.year = 14L, 
    file.month = 12L, file.day = 3L, num.records = 5L, header.length = 193L, 
    record.length = 53L, fields = structure(list(NAME = structure(c(2L, 
    3L, 4L, 1L, 5L), .Label = c("N_________", "N_ID_", "N_ITEMID_", 
    "N_ITEMQTY_", "N_PROVIDER"), class = "factor"), TYPE = structure(c(1L, 
    1L, 1L, 1L, 1L), .Label = "C", class = "factor"), LENGTH = c(5, 
    8, 9, 19, 12), DECIMAL = c(0L, 0L, 0L, 0L, 0L)), .Names = c("NAME", 
    "TYPE", "LENGTH", "DECIMAL"), row.names = c(NA, -5L), class = "data.frame")), .Names = c("file.version", 
"file.year", "file.month", "file.day", "num.records", "header.length", 
"record.length", "fields")), id = structure(integer(0), .Label = character(0), class = "factor")), .Names = c("dbf", 
"header", "id"))

项目

structure(list(dbf = structure(list(N_ID_ = structure(1:3, .Label = c("1", 
"2", "3"), class = "factor"), N_________ = structure(c(3L, 1L, 
2L), .Label = c("Arepas by Dr. Colombia", "Biscotti", "Kolashampan"
), class = "factor"), N_ITEMPRIC = structure(c(2L, 3L, 1L), .Label = c("2", 
"4", "5"), class = "factor")), .Names = c("N_ID_", "N_________", 
"N_ITEMPRIC"), row.names = c(NA, -3L), class = "data.frame", data_types = c("C", 
"C", "C")), header = structure(list(file.version = 3L, file.year = 14L, 
    file.month = 12L, file.day = 3L, num.records = 3L, header.length = 129L, 
    record.length = 40L, fields = structure(list(NAME = structure(c(2L, 
    1L, 3L), .Label = c("N_________", "N_ID_", "N_ITEMPRIC"), class = "factor"), 
        TYPE = structure(c(1L, 1L, 1L), .Label = "C", class = "factor"), 
        LENGTH = c(5, 24, 11), DECIMAL = c(0L, 0L, 0L)), .Names = c("NAME", 
    "TYPE", "LENGTH", "DECIMAL"), row.names = c(NA, -3L), class = "data.frame")), .Names = c("file.version", 
"file.year", "file.month", "file.day", "num.records", "header.length", 
"record.length", "fields")), id = structure(integer(0), .Label = character(0), class = "factor")), .Names = c("dbf", 
"header", "id"))

提供商

structure(list(dbf = structure(list(N_ID_ = structure(1:3, .Label = c("1", 
"2", "3"), class = "factor"), N_______PR = structure(c(3L, 2L, 
1L), .Label = c("Il Italianni", "Rolo Importadora", "Salvadoran Imports"
), class = "factor"), N_LOCATION = structure(c(3L, 1L, 2L), .Label = c("46", 
"64", "9056"), class = "factor"), N_________ = structure(1:3, .Label = c("Dra. Castillo", 
"Dra. Coquita", "Il Ittalianni call center"), class = "factor")), .Names = c("N_ID_", 
"N_______PR", "N_LOCATION", "N_________"), row.names = c(NA, 
-3L), class = "data.frame", data_types = c("C", "C", "C", "C"
)), header = structure(list(file.version = 3L, file.year = 14L, 
    file.month = 12L, file.day = 3L, num.records = 3L, header.length = 161L, 
    record.length = 64L, fields = structure(list(NAME = structure(c(3L, 
    2L, 4L, 1L), .Label = c("N_________", "N_______PR", "N_ID_", 
    "N_LOCATION"), class = "factor"), TYPE = structure(c(1L, 
    1L, 1L, 1L), .Label = "C", class = "factor"), LENGTH = c(5, 
    20, 12, 27), DECIMAL = c(0L, 0L, 0L, 0L)), .Names = c("NAME", 
    "TYPE", "LENGTH", "DECIMAL"), row.names = c(NA, -4L), class = "data.frame")), .Names = c("file.version", 
"file.year", "file.month", "file.day", "num.records", "header.length", 
"record.length", "fields")), id = structure(integer(0), .Label = character(0), class = "factor")), .Names = c("dbf", 
"header", "id"))

1 个答案:

答案 0 :(得分:0)

基本上所有这些时间之后,我通过dplyr学到了更多的 R ,这使我可以做到这一点:

library(dplyr)
library(foreign)

survey <- read.dbf( file.choose(), header="true" )
item <- read.dbf( file.choose(), header="true" )
provider <- read.dbf( file.choose(), header="true" )

# Clean the dataframe names and discard all other parts but dbf
names(survey$dbf) <- c("ID", "ITEMID", "ITEMQTY", "DESCCODE", "PROVIDERID")
survey <- survey$dbf

names(item$dbf) <- c("ID", "ITEMNAME", "ITEMPRICE")
item <- item$dbf

names(provider$dbf) <- c("ID", "PROVIDERNAME", "LOCATIONID", "PRIMARYCONTACT")
provider <- provider$dbf

survey %>%
    inner_join(item, by=c("ITEMID" = "ID")) %>% #join item df
    inner_join(provider, by=c("PROVIDERID" = "ID")) %>% #join provider df
    mutate(ITEMQTY=as.character(ITEMQTY), ITEMPRICE=as.character(ITEMPRICE)) %>% # convert from factor to char
    mutate(TOT_AMOUNT=as.numeric(ITEMQTY)*as.numeric(ITEMPRICE)) %>% # create new colum
    select(ID, DESCCODE, ITEMNAME,TOT_AMOUNT, PROVIDERNAME) %>% # select fields I need
    arrange(ID, DESCCODE) #sort data
# This output can be assigned to a new variable.