当前位置: 首页 > 知识库问答 >
问题:

设置数据表“(组,-值.1)”的显示顺序,同时保留键“id”

符允晨
2023-03-14

是否可以在保留其键的同时存储 data.表中的顺序

假设我有下面的虚拟表:

library(data.table)
dt <- data.table(id=letters[1:6], 
                   group=sample(c("red", "blue"), replace=TRUE), 
                   value.1=rnorm(6), 
                   value.2=runif(6))
setkey(dt, id)
dt
   id group    value.1    value.2
1:  a  blue  1.4557851 0.73249612
2:  b   red -0.6443284 0.49924102
3:  c  blue -1.5531374 0.72977197
4:  d   red -1.5977095 0.08033604
5:  e  blue  1.8050975 0.43553048
6:  f   red -0.4816474 0.23658045

我想存储此表,以便行按group排序,并按value.1按递减顺序排序,即:

> dt[order(group, value.1, decreasing=T),]
   id group    value.1    value.2
1:  f   red -0.4816474 0.23658045
2:  b   red -0.6443284 0.49924102
3:  d   red -1.5977095 0.08033604
4:  e  blue  1.8050975 0.43553048
5:  a  blue  1.4557851 0.73249612
6:  c  blue -1.5531374 0.72977197

显然,我可以将它保存为一个新变量,但是我还想将< code>id列作为我的主键。

Arun对“在data.table中设置键的目的是什么?”建议这可以通过巧妙使用< code>setkey来实现,因为它按照键的顺序对data.table进行排序(尽管没有将键设置为降序的选项):

> setkey(dt, group, value.1, id)
> dt
   id group    value.1    value.2
1:  c  blue -1.5531374 0.72977197
2:  a  blue  1.4557851 0.73249612
3:  e  blue  1.8050975 0.43553048
4:  d   red -1.5977095 0.08033604
5:  b   red -0.6443284 0.49924102
6:  f   red -0.4816474 0.23658045

但是,我无法使用< code>id作为主键,因为< code>group是提供的第一个键:

> dt["a"]
   group id value.1 value.2
1:     a NA      NA      NA

共有3个答案

毕浩渺
2023-03-14

基于@eddi的回答,我创建了一个hackish解决方案,其中我将对order的未评估调用存储为data.table的属性,print.data.table服从:

set_order <- function(dt, cols, decreasing=FALSE) {
  # Store a call to order as an additional attribute
  attr(dt, "order") <- paste0("order(", paste(cols, collapse=", "), 
                              ", decreasing=", decreasing, ")")
  invisible(dt)
}

print.data.table = function(x, ...) {
  if (!is.null(attr(x, "order"))) {
    # Use the stored ordering to print the data.table
    data.table:::print.data.table(x[eval(parse(text=attr(x, "order")))], ...)
  } else {
    data.table:::print.data.table(x, ...)
  }
}

给我想要的行为:

dt <- set_order(dt, c("group", "value.1"), decreasing=T)
dt
#    id group    value.1    value.2
# 1:  f   red -0.4816474 0.23658045
# 2:  b   red -0.6443284 0.49924102
# 3:  d   red -1.5977095 0.08033604
# 4:  e  blue  1.8050975 0.43553048
# 5:  a  blue  1.4557851 0.73249612
# 6:  c  blue -1.5531374 0.72977197

tables()
#      NAME NROW MB COLS                     KEY
# [1,] dt      6 1  id,group,value.1,value.2 id 
# Total: 1MB
鲍国兴
2023-03-14

我认为您仍然可以仅按id搜索,如下所示:

dt[J(unique(group),unique(value.1),"a"), nomatch=0]
   group   value.1 id   value.2
1:  blue 0.4928595  a 0.3311728

据我所知,unique(column_name)是包含该列所有值的方法。

我不确定这是否有帮助。

程景胜
2023-03-14

听起来你只是想修改< code>print.data.table:

print.data.table = function(x, ...) {
  # put whatever condition identifies your tables here
  if ("group" %in% names(x) && "value.1" %in% names(x)) {
    data.table:::print.data.table(x[order(group, value.1, decreasing = T)], ...)
  } else {
    data.table:::print.data.table(x, ...)
  }
}

set.seed(2)
dt = data.table(id=letters[1:6], 
               group=sample(c("red", "blue"), replace=TRUE), 
               value.1=rnorm(6), 
               value.2=runif(6))
setkey(dt, id)
dt
#   id group     value.1    value.2
#1:  a   red  0.18484918 0.40528218
#2:  e   red  0.13242028 0.44480923
#3:  c   red -1.13037567 0.97639849
#4:  b  blue  1.58784533 0.85354845
#5:  f  blue  0.70795473 0.07497942
#6:  d  blue -0.08025176 0.22582546

dt["c"]
#   id group   value.1   value.2
#1:  c   red -1.130376 0.9763985
 类似资料:
  • Java集是否保持顺序?一个方法返回一个集合给我,假设数据是有序的,但是在集合上迭代,数据是无序的。有更好的方法来管理这个吗?这个方法需要改变来返回集合以外的东西吗?

  • 然而,顺序是将示例5放在底部,而不是在其正确的位置。在阅读之后,我意识到对象键没有正确排序(按键排序JavaScript对象),并且JSON键不能是整数(按键排序JavaScript对象)。我需要保留对象顺序,而不是自动排序。原因是它的一个ID必须保持不变(所以没有数组替代)。 我是错过了一些简单的东西,还是需要重新思考/工作?

  • 我似乎正在与光束中的这种模式作斗争。这是一个流式管道。 在高水平上: 消息传入兔子 消息内容包括一个ID和N个S3文件路径 我希望在列出的所有S3文件中产生一些聚合,但结果应该由原始消息键控 向rabbit写一条带有聚合结果的消息,每个传入消息一条 不可避免的是,我最终得到了一些,并希望在上应用一系列,但不要忘记它们最初是由键控的。 我似乎找不到一个通用的“映射KV pcollection的值但保

  • 我在计算一个键的出现次数时遇到了一些问题,同时也保留了几个值。 通常我只会: 它给出了每个关键点的出现次数。 但是,我还希望在计算键的出现次数的同时,保留键每次出现的值。类似这样: 例如:如果键x(1)是一个国家,而x(2)是一个城市,那么我想保留一个国家的所有城市,并知道一个国家有多少个城市。

  • 假设我有一个包含3个应用程序的流——一个源、处理器和接收器。 我需要保留从源收到的消息的顺序。当我收到消息A,B,C,D,我必须将它们作为A,B,C,D.发送到接收器(我不能将它们作为B,A,C,D)发送。 如果每个应用程序只有一个实例,那么一切都将按顺序运行,并且顺序将被保留。 如果我每个应用程序有 10 个实例,则消息 A、B、C、D 可能会在不同的实例中同时处理。我不知道这些消息的顺序是什么

  • 我有一个可用的列表名,我正在按blockIndex属性对这些列表进行排序和分组,如下所示: 问题是分组的结果不按block Index排序。