【问题标题】:How to filter and perform group operation for each row on already filtered data table如何对已过滤的数据表上的每一行进行过滤和分组操作
【发布时间】:2018-02-26 01:02:02
【问题描述】:

我想过滤数据表并对过滤后的数据表的每一行进行一些计算。我知道我可以分两步完成:1) 过滤数据表并分配给新对象,2) 在已过滤的表上计算我需要的内容。

但是有没有办法一步完成呢? IE。一种在by= 参数中使用过滤表的行数的方法? 我的样本数据:

test <- data.frame(min_date = c("2017-08-03", "2017-09-10", "2017-10-03"),
               max_date = c("2017-08-10", "2017-10-12", "2017-11-01"),
               group = c("g1", "g2", "g1"), loc = c("1", "2", "1"))

我只想过滤g1 组,并为每条记录在 min_date 和 max_date 之间的每一天添加新行。

如果不过滤,我会这样做:

dt <- setDT(test)[ , list(group = group, loc = loc,
                                  min_date = min(as.Date(min_date)),
                                  max_date = max(as.Date(max_date)),
                                  loc = loc,
                                  date = seq(as.Date(min_date),
                                             as.Date(max_date),
                                             by = "day")),
              by = 1:nrow(test)]

通过过滤,如果我知道过滤后的行数:

dt <- setDT(test)[group == "g1", list(group = group, loc = loc,
                                  min_date = min(as.Date(min_date)),
                                  max_date = max(as.Date(max_date)),
                                  loc = loc,
                                  date = seq(as.Date(min_date),
                                             as.Date(max_date),
                                             by = "day")),
              by = 1:2]

问题是,我不能使用硬编码的行数和nrow(test) 以及.N 返回原始数据集的行数。

进行过滤然后按操作分组的最快方法是什么?过滤、分配给新对象和执行分组是唯一(也是最好的)方法吗?

谢谢!

【问题讨论】:

  • 可能是by = sequence(test[group == "g1", .N]) 或by = test[group == "g1", .I] 或类似的东西?
  • @A5C1D2H2I1M1N2O1R2T1 这是推荐的方式吗?在这种情况下,我希望获得一些性能非常好的解决方案,因为我有很多数据。您是否会建议先设置一个密钥,然后在 by 参数中使用该密钥?谢谢!
  • 我不确定。还没有真正检查过它们。另一种选择是使用.N 作为第一步,稍后将其用于您的by。也许像test[, nrows := .N, group][group == "g1", blah_blah_blah, by = sequence(nrows[1])] 这样的东西。 “blah_blah_blah”是你想要做的计算。应该足够快,并且可读性强。

标签: r group-by data.table where


【解决方案1】:

将 cmets 中的三个建议移至答案,您可以尝试以下方法之一(按nchar 排序,而不是按性能排序,因为我不知道您必须重新创建可比较的大样本数据进行测试的条件性能):

test[group == "g1", thing_you_want_to_do, test[group == "g1", .I]]
test[group == "g1", thing_you_want_to_do, seq_len(test[group == "g1", .N])]
test[, nrows := .N, group][group == "g1", thing_you_want_to_do, by = seq_len(nrows[1])]

显然,用您的实际计算替换thing_you_want_to_do。

【讨论】:

  • 最后,我选择了第一种方法。在我的情况下,它的性能与第二个大致相同,并且比第三个更容易调整到我的确切情况(多个组,每个组由多列中的值组成,在函数中使用......)。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2022-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多