【问题标题】:Fastest way to match strings with values contained in another data frame in R将字符串与 R 中另一个数据帧中包含的值匹配的最快方法
【发布时间】:2014-05-08 21:28:45
【问题描述】:

抱歉,标题笨拙,我无法优雅地说出我需要做的事情。下面是一些示例代码:

a = c("12_36","13_47","10_55")
b = c("15_47")
c = NULL
d = c("Trader1", "Trader2", "Trader3","Trader4")
Profits = data.frame(Traders = d, Value = I(list(a,b,b,c)), 
                     Cost = I(list(b,a,c,a)), 
              Date = as.Date(c("2011-08-01",
                               "2011-08-02","2011-08-03","2011-08-04")))
Reference = data.frame(Index = rep(c(a,b), 4), 
                       MktPrice = c(1,4,5,6,
                                    2,3.5,7.0,8.574,
                                    9.2345,1.689,0.567,4.5362,
                                    2.35,7.66673,7.88893,6.1221),
                       Date = as.Date(c("2011-08-01","2011-08-01",
                                        "2011-08-01","2011-08-01",
                                        "2011-08-02","2011-08-02",
                                        "2011-08-02","2011-08-02",
                                        "2011-08-03","2011-08-03",
                                        "2011-08-03","2011-08-03",
                                        "2011-08-04","2011-08-04",
                                        "2011-08-04","2011-08-04")))

这会创建两个数据框。第一个利润包含四列:第一列包含虚拟市场中交易者的姓名。第二个和第三个为每个交易者包含一个字符串向量,代表他们收到或交易掉的物品。这些字符串对应于 Reference 中包含每天的“市场价格”的值。最后一列利润是该交易的日期。

现在我要做的是获取利润的价值和成本列中每个项目的价值, 找到每个项目对应的市场价格,然后从 Cost 项目的价格中减去 Value 项目的价格,并将这个总和作为利润的第五列。

所以我想知道最好的方法是什么?我认为这将是某种嵌套函数来遍历 Value 和 Cost 然后与 Reference 匹配,但我不确定是什么(plyr?)。速度也很重要,因为实际的数据帧都很大。 提前谢谢!

【问题讨论】:

  • 首先,将列表存储在 data.frame 中并不是一个好主意。 R 中没有任何东西很好地支持这一点。最好对该表进行反规范化以使操作更好。其次,您打算如何处理 NULL 值?这会使减法变得非常困难。
  • 嗯我也可以有一个版本的表格,而不是列表,会有另一列可以识别交易,所以每个项目都在一行上。至于 NULL 值,它们将被视为零。

标签: r list dataframe plyr


【解决方案1】:

所以我修改了示例以使用 NA 而不是 NULL

a = c("12_36","13_47","10_55")
b = c("15_47")
c = NA
d = c("Trader1", "Trader2", "Trader3","Trader4")
Profits = data.frame(
    Traders = d, Value = I(list(a,b,b,c)), 
    Cost = I(list(b,a,c,a)), 
    Date = as.Date(c("2011-08-01",
        "2011-08-02","2011-08-03","2011-08-04"))
)
Reference = data.frame(
    Index = rep(c(a,b), 4), 
    MktPrice = c(1,4,5,6,
    2,3.5,7.0,8.574,
    9.2345,1.689,0.567,4.5362,
    2.35,7.66673,7.88893,6.1221),
    Date = as.Date(c("2011-08-01","2011-08-01",
    "2011-08-01","2011-08-01","2011-08-02",
    "2011-08-02","2011-08-02","2011-08-02",
    "2011-08-03","2011-08-03","2011-08-03",
    "2011-08-03","2011-08-04","2011-08-04",
    "2011-08-04","2011-08-04"))
)

然后我去规范化利润

dProfits<-do.call(rbind, lapply(seq.int(nrow(Profits)), function(i) {
    data.frame(Traders = Profits[i,1],
        Value = Profits[i,2][[1]],
        Cost = Profits[i,3][[1]],
        Date = Profits[i,4]
       ,stringsAsFactors=F)
}))

然后我使用了标准的合并类型程序

mm<-merge(dProfits, Reference, 
    by.x=c("Value","Date"), by.y=c("Index","Date"))
mm<-merge(mm, Reference, , suffixes=c("",".Cost"),
    all.x=T, by.x=c("Cost","Date"), by.y=c("Index","Date"))
mm<-transform(mm,diff = MktPrice - MktPrice.Cost)

您必须了解它是如何在您的数据上运行的。与标准 data.frame 相比,使用 data.table 可能会获得更好的合并性能

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-05
    • 2016-12-10
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2017-03-29
    • 1970-01-01
    相关资源
    最近更新 更多