【问题标题】:How to find percent values by joining to column from another data.table如何通过加入来自另一个 data.table 的列来查找百分比值
【发布时间】:2016-10-21 09:52:07
【问题描述】:

我已经建立了一个 data.table 数据框dt1,比如:

State Bounced Opened Delivered
FL    2       1      0
NY    0       1      1

我还有另一个 data.table dt2 的总值:

State Total
NY    2
FL    3   

我想找出第一个数据表中每一列的频率百分比:

State Bounced Opened Delivered
FL    66.66   33.33  0
NY    0       50     50

如果我只是* 100 并将所有第一个数据表除以第二个数据表的 Total 列,我有结果,但第一列的州名称变成了 NA,这不好。

如果我喜欢:

dt1[, percen:=Bounced/dt2$Total]

它有效,但我必须对所有列重复该过程。有没有办法复制到除第一列之外的所有列?

第二个问题:检查使用的 Total 值是否正确(即属于正确的状态)的最佳方法是什么?到目前为止,我所做的只是按字母顺序对 State 列进行排序,但我想知道 data.table 是否提供了一种在执行百分比时控制它的方法......

【问题讨论】:

  • 这称为 df1、df2 之间的join 操作。在这种情况下,我们是否进行左连接或右连接以及内连接或外连接都没有关系,因为这两个 dfs 状态都已完全填充。您的第二个问题是多余的,因为如果您执行join,它将获得跨表的订单。
  • 感谢指点,建议使用merge?
  • 好吧,如果它们是普通数据框,可以加入 merge。如果它们是数据表,请使用 DT's join syntax

标签: r join data.table


【解决方案1】:

这是一个连接操作,所以使用 data.table 连接语法,它是单行的:

dt1 <- data.table(State=c('FL','NY'), Bounced=c(2,0),
                  Opened=c(1,1), Delivered=c(0,1), key='State')
dt2 <- data.table(State=c('NY','FL'), Total=c(2,3), key='State')

colsToDivide = c('Bounced','Opened','Delivered')

dt1[dt2, (colsToDivide) :=
  lapply(mget(colsToDivide), function(x) {100*x/Total} ) ]

#   State  Bounced   Opened Delivered
#1:    FL 66.66667 33.33333         0
#2:    NY  0.00000 50.00000        50

【讨论】:

  • 谢谢,虽然没有使用连接,但我在问题中明确说明了实现此目的的解决方案,但要求提供一种可以管理所有列而不显式命名每个列的解决方案(我还有更多) ...有我可以参考的 data.table 语法吗?
  • 我猜是df1[df2, names(df1)[-1] := WHATHERE? ]的东西
  • 是的,它可以做到,使用lapply,我正在尝试得到它。请参阅DT divide list of columns by a second list of columns,这更难。
  • 您可以使用mget 按名称获取列列表。
  • ...并参数化了我们想要划分的所有 var 名称...我查看了Dynamically build call for lookup multiple columns 并在 RHS 上使用了mget。虽然它很丑陋。呸!
【解决方案2】:

我不太擅长 data.table ,但是,我认为这会奏效。

cbind(State = df1$State, 
      df1[, -1, with = FALSE]/df2$Total[match(df1$State, df2$State)]* 100)

#   State  Bounced   Opened  Delivered
#1:    FL  66.667    33.333         0
#2:    NY  0.000     50.000        50

考虑到df1df2data.table

这也将回答您的第二个问题,因为它 matches 是 df1 中的 Statedf2 中的 df2

【讨论】:

  • 谢谢,也许我的问题不是很清楚,但我想在最终结果中保留 State 列
  • 真的应该使用merge(),这是一个连接。 merge 性能更高,并且可以显式处理某些列丢失/不匹配的情况。
  • @smci 你的意思是说merge(df1, df2, by = "State"),然后取Total 值并将其除以整个?。有没有办法可以在合并操作本身中完成?
  • 因为它们实际上是 data.tables,所以使用DT's join syntax。内连接就是dt1[dt2]。阅读它here
  • 好的我已经全部转换为data.table并设置了key,所以现在join很简单,但是如何更改答案中的代码以获得相同的结果呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多