2016-07-14 55 views
0

我有一个data.frame,如下所示。对于name列中的每组不同值,我想要颠倒ID列的顺序。我不想触摸其余的列。我的数据非常庞大。我应该如何有效地做到这一点?R:只根据另一列更改少量列的顺序

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 
+0

在你的情况,你可以,也许只是做'维护[顺序(MAINT $名称,-maint $ ID),]'或'data.table :: setorder (maint,name,-ID)'如果你需要效率。或者用'(maint,ave(ID,name,FUN = function(x)sort(x,decrease = TRUE)))' –

+0

我不确定第一个建议是否可行。因为它将排序开始和结束日期字段,因为我们按降序对ID进行排序 – user2543622

+0

在这种情况下,第三个选项。或'library(data.table); setDT(maint)[,ID:= sort(ID,decrease = TRUE),by = name]'或者类似于dplyr –

回答

0

您将要确保您的数据帧由名头排序。你的例子是排序的,但你的数据可能不是。 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 
+0

这应该是组 –

+0

错过了,这应该起作用。 – JMT2080AD

+0

在我的数据中,ID列实际上是一个日期字段,它被称为newstart,我得到一个错误。出了什么问题? '-Date'中的错误(maint $ newstart): unary - 没有为“Date”对象定义# – user2543622