【问题标题】:R: change order of few columns only based upon another columnR:仅基于另一列更改几列的顺序
【发布时间】:2016-07-14 21:17:04
【问题描述】:

我有一个如下的data.frame。对于name 列中的每组不同值,我想颠倒ID 列的顺序。我不想触摸其余的列。我的数据很大。我应该如何有效地做到这一点?

ID=c(466,469,471,480,509,513,515,517,518,519,520,521,453,455,463,474,477,479,481,482,484,489,496,497,500,503)
name=c(rep("a",12),rep("b",14))
start=c(rep("2/13/2013",12),rep("3/6/2013",14))
end=c(rep("2/20/2013",12),rep("3/13/2013",14))
start=as.Date(start,"%m/%d/%Y")
end=as.Date(end,"%m/%d/%Y")

maint=data.frame(ID,name,start,end)

数据如下所示

ID  name    start   end
466 a   2/13/2013   2/20/2013
469 a   2/13/2013   2/20/2013
471 a   2/13/2013   2/20/2013
480 a   2/13/2013   2/20/2013
509 a   2/13/2013   2/20/2013
513 a   2/13/2013   2/20/2013
515 a   2/13/2013   2/20/2013
517 a   2/13/2013   2/20/2013
518 a   2/13/2013   2/20/2013
519 a   2/13/2013   2/20/2013
520 a   2/13/2013   2/20/2013
521 a   2/13/2013   2/20/2013
453 b   3/6/2013    3/13/2013
455 b   3/6/2013    3/13/2013
463 b   3/6/2013    3/13/2013
474 b   3/6/2013    3/13/2013
477 b   3/6/2013    3/13/2013
479 b   3/6/2013    3/13/2013
481 b   3/6/2013    3/13/2013
482 b   3/6/2013    3/13/2013
484 b   3/6/2013    3/13/2013
489 b   3/6/2013    3/13/2013
496 b   3/6/2013    3/13/2013
497 b   3/6/2013    3/13/2013
500 b   3/6/2013    3/13/2013
503 b   3/6/2013    3/13/2013

最终数据应如下所示

ID  name    start   end
521 a   2/13/2013   2/20/2013
520 a   2/13/2013   2/20/2013
519 a   2/13/2013   2/20/2013
518 a   2/13/2013   2/20/2013
517 a   2/13/2013   2/20/2013
515 a   2/13/2013   2/20/2013
513 a   2/13/2013   2/20/2013
509 a   2/13/2013   2/20/2013
480 a   2/13/2013   2/20/2013
471 a   2/13/2013   2/20/2013
469 a   2/13/2013   2/20/2013
466 a   2/13/2013   2/20/2013
503 b   3/6/2013    3/13/2013
500 b   3/6/2013    3/13/2013
497 b   3/6/2013    3/13/2013
496 b   3/6/2013    3/13/2013
489 b   3/6/2013    3/13/2013
484 b   3/6/2013    3/13/2013
482 b   3/6/2013    3/13/2013
481 b   3/6/2013    3/13/2013
479 b   3/6/2013    3/13/2013
477 b   3/6/2013    3/13/2013
474 b   3/6/2013    3/13/2013
463 b   3/6/2013    3/13/2013
455 b   3/6/2013    3/13/2013
453 b   3/6/2013    3/13/2013

【问题讨论】:

  • 在你的情况下,如果你需要效率,你可以只做maint[order(maint$name, -maint$ID),]data.table::setorder(maint, name, -ID)。或with(maint, ave(ID, name, FUN = function(x) sort(x, decreasing = TRUE)))
  • 我不确定第一个建议是否可行。因为它会对开始和结束日期字段进行排序,因为我们按降序对 ID 进行排序
  • 在这种情况下是第三个选项。或 library(data.table) ; setDT(maint)[, ID := sort(ID, decreasing = TRUE), by = name] 或类似的 dplyr

标签: r sorting multiple-columns


【解决方案1】:

您需要确保您的数据框首先按名称排序。您的示例已排序,但您的数据可能未排序。 dplyr 解决方案可能更快。

当 ID 是日期时:

ID <- as.Date(c(25:50), '1999-1-1')
ID <- sample(ID, length(ID))
name <- c(rep("a",12),rep("b",14))
start <- c(rep("2/13/2013",12),rep("3/6/2013",14))
end <- c(rep("2/20/2013",12),rep("3/13/2013",14))
start <- as.Date(start,"%m/%d/%Y")
end <- as.Date(end,"%m/%d/%Y")

maint=data.frame(ID,name,start,end)

maint$ID <- maint$ID[order(maint$name, -rank(maint$ID))]

head(maint, 50)

           ID name      start        end
1  1999-02-20    a 2013-02-13 2013-02-20
2  1999-02-17    a 2013-02-13 2013-02-20
3  1999-02-15    a 2013-02-13 2013-02-20
4  1999-02-12    a 2013-02-13 2013-02-20
5  1999-02-11    a 2013-02-13 2013-02-20
6  1999-02-10    a 2013-02-13 2013-02-20
7  1999-02-06    a 2013-02-13 2013-02-20
8  1999-02-05    a 2013-02-13 2013-02-20
9  1999-02-03    a 2013-02-13 2013-02-20
10 1999-02-01    a 2013-02-13 2013-02-20
11 1999-01-31    a 2013-02-13 2013-02-20
12 1999-01-26    a 2013-02-13 2013-02-20
13 1999-02-19    b 2013-03-06 2013-03-13
14 1999-02-18    b 2013-03-06 2013-03-13
15 1999-02-16    b 2013-03-06 2013-03-13
16 1999-02-14    b 2013-03-06 2013-03-13
17 1999-02-13    b 2013-03-06 2013-03-13
18 1999-02-09    b 2013-03-06 2013-03-13
19 1999-02-08    b 2013-03-06 2013-03-13
20 1999-02-07    b 2013-03-06 2013-03-13
21 1999-02-04    b 2013-03-06 2013-03-13
22 1999-02-02    b 2013-03-06 2013-03-13
23 1999-01-30    b 2013-03-06 2013-03-13
24 1999-01-29    b 2013-03-06 2013-03-13
25 1999-01-28    b 2013-03-06 2013-03-13
26 1999-01-27    b 2013-03-06 2013-03-13

【讨论】:

  • 这应该是分组
  • 在我的数据中,ID 列实际上是一个日期字段,它被称为 newstart,我收到了一个错误。出了什么问题? Error in -.Date(maint$newstart) : unary - is not defined for "Date" objects
  • 删除了我的最后一条评论。我把等级和顺序搞混了。为此,我认为您需要将您的 ID 列(这实际上是一个日期)包装在排名中。这将为它提供一个唯一的数字 ID,您可以将其倒序排列。希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
相关资源
最近更新 更多