【问题标题】:Merging 2 data.tables in R where 1 data table has an extra row在 R 中合并 2 个 data.tables,其中 1 个数据表有一个额外的行
【发布时间】:2021-07-01 22:50:00
【问题描述】:

所以我一直在尝试合并这两个看起来像这样的data.tables

structure(list(orderDate = structure(c(18414, 18444, 18475, 18506, 
18536, 18567, 18597, 18628, 18659, 18687, 18718, 18748, 18779
), class = "Date"), productName = c("A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady"), totalOrders = c(2L, 
15L, 52L, 225L, 27L, 10L, 5L, 19L, 36L, 41L, 58L, 16L, 2L)), row.names = c(NA, 
-13L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x0000024e1b7d1ef0>, sorted = "orderDate")

structure(list(returnDate = structure(c(18444, 18475, 18506, 
18536, 18567, 18597, 18628, 18659, 18687, 18718, 18748, 18779
), class = "Date"), productName = c("A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
"A. De La Sota Lady"), totalReturns = c(5L, 10L, 129L, 73L, 18L, 
3L, 8L, 15L, 43L, 44L, 30L, 6L), orderDate = structure(c(18444, 
18475, 18506, 18536, 18567, 18597, 18628, 18659, 18687, 18718, 
18748, 18779), class = "Date")), row.names = c(NA, -12L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x0000024e1b7d1ef0>, sorted = "orderDate")

结果是合并的data.table

structure(list(orderDate = structure(c(18444, 18475, 18506, 18536, 
18567, 18597, 18628, 18659, 18687, 18718, 18748, 18779), class = "Date"), 
    productName = c("A. De La Sota Lady", "A. De La Sota Lady", 
    "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
    "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
    "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady", 
    "A. De La Sota Lady"), totalOrders = c(15L, 52L, 225L, 27L, 
    10L, 5L, 19L, 36L, 41L, 58L, 16L, 2L), totalReturns = c(5L, 
    10L, 129L, 73L, 18L, 3L, 8L, 15L, 43L, 44L, 30L, 6L)), sorted = "orderDate", class = c("data.table", 
"data.frame"), row.names = c(NA, -12L), .internal.selfref = <pointer: 0x0000024e1b7d1ef0>)

但是在returnTest 表中缺少一个日期行。

我尝试使用 productName 列作为键列进行合并,但由于某种原因,它一直给我一个错误,这是我可以合并两个表而没有错误的唯一方法。最终,我希望有一个数据表来检查某个产品的退货率,但是使用这种方法,我总是错过一个月我可以有订单但没有退货的月份,反之亦然。有人可以帮忙吗?我已经尝试解决这个问题大约一周了。

test1  <- ordersByProductNameAndSize[`productName` == 'A. De La Sota Lady'  ] 
setkeyv(test1, 'orderDate')

test2 <- returnsByProductNameAndSize[`productName` == 'A. De La Sota Lady'  ]
test2[, 'orderDate' := returnDate]
setkeyv(test2, 'orderDate'
  
returnTest <- merge(test1, test2[, c('orderDate', 'totalReturns'), all = TRUE, with = FALSE]) # , 'totalReturns' 
returnTest[, 'returnRate' := ((totalReturns / totalOrders) *100)] 

【问题讨论】:

  • 请不要发布数据图像,很少有人会尝试将您的数据转录成可用的东西。最好将dput(x) 的输出粘贴到code block 中,其中x 的行/列足以说明问题。
  • 来自@Skaggs:你在合并中使用all=TRUE吗?
  • 我很想这样做,但我实际上不知道你在说什么,也不知道怎么做,我尝试在我的测试 1 变量上使用 dput() 函数但没有不知道如何处理它而不是如何在这里上传它,是的,我只是在合并中使用了all = TRUE,但仍然有同样的问题@r2evans
  • @r2evans 也许是时候更新你的 .NORM 包了 ;-)..xkcd.com/2116
  • @Greg 我正在使用 data.table 来提高速度,因为我也在尝试开发一个闪亮的应用程序,所以我认为我需要所有能得到的性能提升,呵呵。但是,我还需要根据需要使用 data.table 进行实习。

标签: r data.table


【解决方案1】:

感谢您发布您的数据!如果我理解正确,您的“缺失”值只是在 2020 年 6 月 1 日订购了一件商品,但在该日期没有任何退货的情况,对吗?

t1 <- structure(list(
  orderDate = structure(c(18414, 18444, 18475, 18506,  18536, 18567, 18597, 18628, 18659, 18687, 18718, 18748, 18779 ), class = "Date"),
  productName = c("A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady"),
  totalOrders = c(2L,  15L, 52L, 225L, 27L, 10L, 5L, 19L, 36L, 41L, 58L, 16L, 2L)),
  row.names = c(NA,  -13L),
  class = c("data.table", "data.frame"))

t2 <- structure(list(
  returnDate = structure(c(18444, 18475, 18506,  18536, 18567, 18597, 18628, 18659, 18687, 18718, 18748, 18779 ), class = "Date"),
  productName = c("A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady", "A. De La Sota Lady", "A. De La Sota Lady",  "A. De La Sota Lady"),
  totalReturns = c(5L, 10L, 129L, 73L, 18L,  3L, 8L, 15L, 43L, 44L, 30L, 6L),
  orderDate = structure(c(18444,  18475, 18506, 18536, 18567, 18597, 18628, 18659, 18687, 18718,  18748, 18779), class = "Date")),
  row.names = c(NA, -12L),
  class = c("data.table",  "data.frame"))

rt <- merge(t1, t2, by = "orderDate", all = TRUE)

# calculate return rate
rt$returnRate <- (rt$totalReturns / rt$totalOrders) * 100

【讨论】:

  • 没错!我使用了参数all = TRUE,但我仍然有这个缺失值。我还考虑过可能为我有订单但没有退货的月份添加一个“0”值,但后来我意识到在某些时候我会遇到除以 0 的情况,而我有退货但在特定月份没有订单。
  • 使用我的方法,您的returnRate 在没有返回任何内容的日期是NA。如果您希望此值为 0,请使用 rt$returnRate2 &lt;- ifelse(is.na(rt$returnRate), 0, rt$returnRate)
  • 非常感谢!它起作用了,有点。当我尝试rt$returnRate &lt;- (rt$totalReturns / rt$totalOrders) * 100 时,它返回了Error in rt$totalReturns : object of type 'closure' is not subsettable 但是,我能够使用相同的方法来计算退货率而不使用$
  • data.table 代码高尔夫:rt &lt;- merge(t1, t2, all = TRUE)[, returnRate := 100 * totalReturns / totalOrders]。通常,最好明确列出 by= 字段,以防它曾经以编程方式/无监督方式进行评估。
  • 仅供参考,在 R 中,“闭包”是函数及其封闭环境的花哨术语。例如,先执行func &lt;- function(x) {...} 然后执行func$quux 是没有意义的,因为不会在函数上使用$(子集)。好吧,现在意识到,如果没有另外定义,R 将 rt 视为函数 stats::rt,人们可能会开始意识到不将变量命名为与基本 R 函数名称相同的值。这是一个很难改掉的习惯,我仍然经常这样做,但结果可能会令人困惑。但现在你知道'closure' is not subsettable 的真正含义了:-)
猜你喜欢
  • 2017-07-11
  • 2014-04-28
  • 2016-05-01
  • 2012-04-13
  • 2021-12-20
  • 2017-06-29
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多