【问题标题】:Index unique values in data.table索引 data.table 中的唯一值
【发布时间】:2016-02-12 20:08:22
【问题描述】:

不知道如何用文字表达问题,但是如何为 data.table 创建一个索引列,当出现不同值时每组递增?

这里是 MWE

library(data.table)
in.data <- data.table(fruits=c(rep("banana", 4), rep("pear", 5)),vendor=c("a", "b", "b", "c", "d", "d", "e", "f", "f"))

这是 R 代码应该生成的结果

in.data[, wanted.column:=c(1,2,2,3,1,1,2,3,3)]

#    fruits vendor wanted.column
# 1: banana      a             1
# 2: banana      b             2
# 3: banana      b             2
# 4: banana      c             3
# 5:   pear      d             1
# 6:   pear      d             1
# 7:   pear      e             2
# 8:   pear      f             3
# 9:   pear      f             3

因此,它在每个水果中标记每个供应商 1、2、3……。可能有一个非常简单的解决方案,但我被卡住了。

【问题讨论】:

  • 成功了!我是这样添加的:in.data[, Wanted.2:=in.data[, rleid(vendor), by=fruits][, V1]]。也许你可以写一个答案让我接受?

标签: r data.table


【解决方案1】:

我有一些想法。您可以使用嵌套组计数器:

in.data[, w := setDT(list(v = vendor))[, g := .GRP, by=v]$g, by=fruits]

或者,创建一个运行 ID,它依赖于排序的数据(感谢 @eddi)并且看起来很浪费:

in.data[, w := rleid(vendor), by=fruits]

base-R 方法可能是:

in.data[, w := match(vendor, unique(vendor)), by=fruits]

# or in base R ...

in.data$w = with(in.data, ave(vendor, fruits, FUN = function(x) match(x, unique(x))))

【讨论】:

  • 谢谢!我自己永远无法解决它。
  • 值得注意的是,如果你这样做,第一个和第二个选项会产生不同的结果,例如in.data[6, vendor := 'f']。我不确定哪一个是想要的结果。
  • 我计划在运行操作之前对数据进行排序,所以两者都会给我相同的结果。感谢您的评论,我学到了很多东西。
【解决方案2】:

另一种方法可能是两个步骤:

DT = data.table(fruits=c(rep("banana", 4), rep("pear", 5)),vendor=c("a", "b", "b", "c", "d", "d", "e", "f", "f"))
DT
   fruits vendor
1: banana      a
2: banana      b
3: banana      b
4: banana      c
5:   pear      d
6:   pear      d
7:   pear      e
8:   pear      f
9:   pear      f
DT[, wanted:=.GRP, by="fruits,vendor"]  # step 1
DT
   fruits vendor wanted
1: banana      a      1
2: banana      b      2
3: banana      b      2
4: banana      c      3
5:   pear      d      4
6:   pear      d      4
7:   pear      e      5
8:   pear      f      6
9:   pear      f      6
DT[, wanted:=wanted-wanted[1]+1L, by="fruits"]  # step 2 (adjust)
DT
   fruits vendor wanted
1: banana      a      1
2: banana      b      2
3: banana      b      2
4: banana      c      3
5:   pear      d      1
6:   pear      d      1
7:   pear      e      2
8:   pear      f      3
9:   pear      f      3
> 

我会在生产代码中对此进行评论的方式可能是:

DT[, wanted:=.GRP, by="fruits,vendor"]          # .GRP is simple group counter
DT[, wanted:=wanted-wanted[1]+1L, by="fruits"]  # reset vendor counter per fruit

【讨论】:

  • 谢谢。我在生产中使用 R,因此感谢您提供的示例。 data.table 对我来说仍然很神奇,但我希望最终能理解它。
  • @Chris 很高兴听到。看来你快到了。很高兴看到一个好的 MRE。
  • @Chris 虽然,您的 MRE 留下了一些模棱两可的方面,这造成了混乱。通过包含不连续的组并说明期望的结果是什么,MRE 可能会更好。
【解决方案3】:

如果您希望给定水果中所有供应商的索引相同,那么这是另一种选择:

in.data[, wanted := as.integer(factor(vendor, levels = unique(vendor))), by = fruits]

否则,如果您希望它在每次供应商更改时都打勾,那么从目前给出的答案来看,rleid 是唯一有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多