【问题标题】:Merging multiple data tables (or Replacing values from other lists) in R在 R 中合并多个数据表(或替换其他列表中的值)
【发布时间】:2014-08-01 15:34:40
【问题描述】:

所有,我希望你能帮助我解决这个问题。是的,我已经在这里和其他网站上查找了潜在的解决方案,但到目前为止还没有运气。

我有一个大数据表(总共 357 个变量),我需要将其中的三个变量与其存储在单独列表中的描述相匹配。我也将这些列表转换为 data.table,因为我认为这将有助于合并过程。

所以,例如在 dt 中:

Market    Store    Product var-1 ... var-n  
2         1        1       XYZ GHY HHH ABC ZZZ
1         1        3       XYZ HJK III CDE FFF
2         3        1       GHY JUU JJJ JJJ KKK
2         1        1       HHH UUU JJJ JJJ HHH

当我将数据加载到 dt 中时,MarketStoreProduct 被存储为 Factors,但我将它们转换为数字,因为我认为这也有助于合并。

在marketdesc、storedesc和productdesc中对应的表很简单,例如——在marketdesc中:

idx   marketdesc
1     North/West
2     North
3     North/East
4     East
5     South/East
6     South
7     South/West
8     West

我想作为最终表创建的是一个 data.table,它可以独立地进行进一步分析,而无需从其他表中查找值,例如

Market       Store     Product   var-1 ... var-n
North        Chain X   Apple     XYX GHY HHH ABC ZZZ
North/West   Chain X   Banana    XYZ HJK III CDE FFF
North        Chain Z   Apple     GHY JUU JJJ JJJ KKK
North        Chain X   Apple     HHH UUU JJJ JJJ HHH

由于 data.table 不喜欢 by.x 和 by.y,我将 idx 更改为与查找表中的变量名相同的变量名,并执行以下操作:

dt1 <- merge(dt,marketdesc,by="Market")
dt2 <- merge(dt1,storedesc,by="Store")
dt3 <- merge(dt2,productdesc,by="Product")

这不是最有效和最优雅的编码,我知道它也不是内存管理的最佳方法——但我的 R 技能仍然非常有限。有人知道解决问题的更好方法吗?

非常感谢任何建议!

编辑

以下创建示例数据表(不包括暂时不需要的 var-1 ... var-n):

library(data.table)
dt <- data.table(Market=c('2','1','2','2'),Store=c('1','1','3','1'),Product=c('1','2','1','1')) 
marketdesc <- data.table(Market=1:8,desc=c('North/West','North','North/East','East','South/East','South','South/West','West'))
storedesc <- data.table(Store=1:3,desc=c('Chain X','Chain Y','Chain Z'))
productdesc <- data.table(Product=1:5,desc=c('Apple','Orange','Banana','Strawberry','Pineapple'))

执行合并构造需要我删除原始列,然后在每一步之后用旧变量名重命名“desc”。

任何指针表示赞赏。

【问题讨论】:

  • 请提供一个可重现的例子。
  • 斯文 - 谢谢你的建议。我已经提供了代码 sn-p 来生成示例数据。
  • 听起来你正在做的工作很好。您的目标是简单地减少所需的代码量吗?我认为 data.table 不必重命名和删除列本身就效率低下。

标签: r merge data.table


【解决方案1】:

我更喜欢使用sqldf 包来完成我所有的表连接,因为这似乎正是制作 sql 的原因。所以对于你的例子:

#convert all to data.frames, sqldf doesn't work with data.table (yet)

require(sqldf)
df <- data.frame(dt)
md <- data.frame(marketdesc)
sd <- data.frame(storedesc)  ## I realize that is overwrites the sd function, but too lazy at the moment
pd <- data.frame(productdesc)

df2 <- sqldf('SELECT df.*,md.desc,sd.desc,pd.desc FROM df JOIN md on md.Market=df.Market JOIN sd on sd.Store=df.Store JOIN pd on pd.Product = df.Product')

> df2
  Market Store Product       desc    desc   desc
1      1     1       2 North/West Chain X Orange
2      2     1       1      North Chain X  Apple
3      2     3       1      North Chain Z  Apple
4      2     1       1      North Chain X  Apple

当我得到一个 data.table 特定的答案时,我会更新,但这现在应该可以解决问题。如果需要,您显然可以在最后将其转换回 data.table

这是一个带有 data.table 的单行代码: 注意:我将 desc 表的列名更改为 Thing、ThingDesc(例如 Market、MarketDesc)

> Reduce(function(a,b) merge(a,b,by=intersect(names(a),names(b))), list(dt,marketdesc,storedesc,productdesc))
   Product Store Market MarketDesc StoreDesc ProductDesc
1:       1     1      2      North   Chain X       Apple
2:       1     1      2      North   Chain X       Apple
3:       1     3      2      North   Chain Z       Apple
4:       2     1      1 North/West   Chain X      Orange

函数根据它们都具有的列名合并两个表。 您可以为重复名称添加后缀(请参阅?merge 了解更多信息)。以防万一您遇到更复杂的事情

【讨论】:

  • 谢谢你的回答,詹姆斯。我也会密切关注这个构造对于 data.table 的可用性。
【解决方案2】:

非常感谢大家的建议。

最后,该解决方案在处理多重合并的同时还利用了“:=" data.table 结构。在我自己的数据文件中,我意识到我还必须将存储描述的变量转换为字符(使用 as.character()),否则后续的“合并”命令会抱怨有一个包含非向量数据的变量数据表。

我在示例中也犯了一个错误,将 MarketStoreProduct 存储为字符。

library(data.table)
dt <- data.table(Market=c(2,1,2,2),Store=c(1,1,3,1),Product=c(1,2,1,1)) 
marketdesc <- data.table(Market=1:8,desc=c('North/West','North','North/East','East','South/East','South','South/West','West'))
storedesc <- data.table(Store=1:3,desc=c('Chain X','Chain Y','Chain Z'))
productdesc <- data.table(Product=1:5,desc=c('Apple','Orange','Banana','Strawberry','Pineapple'))

dt1 <- merge(dt,marketdesc,by="Market")
dt1[,Market := desc]
dt1[,desc := NULL]

dt2 <- merge(dt1,storedesc, by="Store")
dt2[,Store := desc]
dt2[,desc := NULL]

dt_fin <- merge(dt2,productdesc, by="Product")
dt_fin[,Product := desc]
dt_fin[,desc := NULL]

我做的最后一步是清理过渡文件(dt、dt1 和 dt2)。

【讨论】:

    猜你喜欢
    • 2016-02-20
    • 1970-01-01
    • 2018-08-04
    • 2019-05-13
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多