R 按特定值顺序对数据表进行排序
下面是一个简短的data.table:R 按特定值顺序对数据表进行排序,r,data.table,R,Data.table,下面是一个简短的data.table: DT <- data.table(Tag1 = c(22,253,6219,6219,252862,252864,312786,312812), Tag2 = c(22,255,6220,252857,252863,252865,251191,252863), Date= as.Date(as.character(c("7/25/2008","6/15/2000","6/30/200
DT <- data.table(Tag1 = c(22,253,6219,6219,252862,252864,312786,312812),
Tag2 = c(22,255,6220,252857,252863,252865,251191,252863),
Date= as.Date(as.character(c("7/25/2008","6/15/2000","6/30/2000","9/6/2002","9/6/2002","9/6/2002","9/3/2003","9/5/2003")),format = "%m/%d/%Y"))
DT
Tag1 Tag2 Date
1: 22 22 2008-07-25
2: 253 255 2000-06-15
3: 6219 6220 2000-06-30
4: 6219 252857 2002-09-06
5: 252862 252863 2002-09-06
6: 252864 252865 2002-09-06
7: 312786 251191 2003-09-03
8: 312812 252863 2003-09-05
特别是,Tag1或Tag1的重复值应一个接一个地处理(例如:Tag1为6219,Tag2为252863)。
我该怎么做
编辑:
建议的解决方案适用于较短的data.table(如上面的data.table)。
下面是一个较长的版本:
DT <- data.table(Tag1 = c(252860, 252862, 312812, 252864, 252866, 252868, 252870, 318880, 252872, 252874, 252876, 252878, 252880, 252880, 252881, 252883,
252885, 252887, 311264, 252889, 252889, 252892, 318879, 318880, 318881), Tag2 = c(252861, 252863, 252863, 252865, 252867, 252869, 252871, 252871, 252873,
252875, 252877, 252879, 414611, 905593, 252882, 252884, 252886, 252888, 252888, 252890, 318904, 252893, 318878, 414547, 318882), Date = c("9/6/2002",
"9/6/2002", "9/5/2003", "9/6/2002", "9/6/2002", "9/6/2002", "9/6/2002", "10/8/2003", "9/6/2002", "9/6/2002", "9/6/2002", "9/6/2002", "10/5/2004",
"9/6/2002", "9/6/2002", "9/6/2002", "9/10/2002", "9/10/2002", "7/15/2003", "9/10/2002", "10/15/2003", "9/10/2002", "10/8/2003", "9/29/2004","10/8/2003"))
DT示例中的数据已经排序,因此下面是一个按未排序顺序排列的简短版本,以说明如何更改排序顺序
> library(data.table)
> DT <- data.table(Tag1 = c(22,253,22,22),
Tag2 = c(1,255,2,2),
Date = as.Date(as.character(c(
"1/1/2010","4/4/2000","3/3/2003","2/2/2000")), format = "%m/%d/%Y"))
> DT
Tag1 Tag2 Date
1: 22 1 2010-01-01
2: 253 255 2000-04-04
3: 22 2 2003-03-03
4: 22 2 2000-02-02
要就地重新排序data.table,请使用setorder
功能
设置顺序(DT、Tag1、Tag2、日期)
如果要按降序排序,请在字段名称上使用-
前缀
> DT[order(Tag1, Tag2, -Date)]
> setorder(DT, Tag1, Tag2, -Date)
旧订单
df[order(Tag1, Tag2, Date)]
# Tag1 Tag2 Date
# 1: 22 22 2008-07-25
# 2: 253 255 2000-06-15
# 3: 6219 6220 2000-06-30
# 4: 6219 252857 2002-09-06
# 5: 252862 252863 2002-09-06
# 6: 252864 252865 2002-09-06
# 7: 312786 251191 2003-09-03
# 8: 312812 252863 2003-09-05
新订单
按降序排列Date
列,然后按Tag2
分组按升序排列Tag1
setcolorder(dt1 <- df[order(-Date)][order(Tag1), .SD, by = Tag2], colnames(df))
dt1
# Tag1 Tag2 Date
# 1: 22 22 2008-07-25
# 2: 253 255 2000-06-15
# 3: 6219 252857 2002-09-06
# 4: 6219 6220 2000-06-30
# 5: 252862 252863 2002-09-06
# 6: 312812 252863 2003-09-05
# 7: 252864 252865 2002-09-06
# 8: 312786 251191 2003-09-03
在对该问题的更新中,OP指出以前的答案(包括接受的答案)在更长的数据集内不起作用。使用问题编辑后的新数据,我们可以如下进行排序:
诀窍是从按日期排序的表开始,然后是按升序排序的标记(OP中的初始数据已经处于这种状态,但出于一般性考虑,我开始确保数据按setkey(DT,asDate,Tag1,Tag2)
排序)。然后按tag2的不同值出现的顺序对其进行编号,并按这些组号进行排序(接下来的两行)。这将确保tag2的相同值彼此跟随,而不会干扰表格的顺序。接下来,对tag1执行相同的操作
DT[, asDate := as.Date(Date, format = "%m/%d/%Y")]
setkey(DT, asDate, Tag1, Tag2)
DT[, g2 := .GRP, Tag2]
setkey(DT, g2)
DT[, g1 := .GRP, Tag1]
setkey(DT, g1)
DT[, c("g1", "g2", "asDate") := NULL][]
Tag1 Tag2 Date
1: 252860 252861 9/6/2002
2: 252862 252863 9/6/2002
3: 312812 252863 9/5/2003
4: 252864 252865 9/6/2002
5: 252866 252867 9/6/2002
6: 252868 252869 9/6/2002
7: 252870 252871 9/6/2002
8: 318880 252871 10/8/2003
9: 318880 414547 9/29/2004
10: 252872 252873 9/6/2002
11: 252874 252875 9/6/2002
12: 252876 252877 9/6/2002
13: 252878 252879 9/6/2002
14: 252880 905593 9/6/2002
15: 252880 414611 10/5/2004
16: 252881 252882 9/6/2002
17: 252883 252884 9/6/2002
18: 252885 252886 9/10/2002
19: 252887 252888 9/10/2002
20: 311264 252888 7/15/2003
21: 252889 252890 9/10/2002
22: 252889 318904 10/15/2003
23: 252892 252893 9/10/2002
24: 318879 318878 10/8/2003
25: 318881 318882 10/8/2003
Tag1 Tag2 Date
注释
这在示例数据上非常有效。不过,我要提醒大家一句。对于所有可能的数据(通过此方法或任何方法)都不能保证存在解决方案,特别是如果重复标记占所有标记的很大一部分。例如,考虑以下列,在这些列中,不可能对行排序,使得相同的字母总是同时出现在两列中:
a b
a c
b a
b c
c a
c b
然后您可能需要中断顺序
。i、 e.DT[,lappy(DT,sort)]
@Sathish这是一个评论,而不是一个答案。这就是我没有发布它的原因。你使用什么样的数据来进行这种分组/排序?这些是带有动物耳朵标签号的捕获数据。我不知道这个顺序背后的逻辑是什么。在您想要的输出中,两列都不是有序的,而是从一个无序状态移动到另一个无序状态。非常感谢JasonM1的回答。我的原始数据表与我的示例类似,即按排序顺序。是否可以使用函数setcolorder
,保留所有data.table列,而不仅仅是三列“Tag1”、“Tag2”和“Date”?例如,我有一个data.table,其中有三列“Tag1”、“Tag2”和“Date”和其他列。当第4行的日期(在data.table Old order中)替换为第3行的日期时,为什么日期不按顺序排序(即第3行为2002-09-06而不是2000-06-30,第4行为2000-06-30而不是2002-09-06?例如:DT在这种情况下是否可以重新安排日期?我在问题中添加了一个更大的数据表:代码不适用于值318880(Tag1)@Nell我几天前添加了这个答案-据我所知,它准确地回答了你的问题。这个答案是否有不适合你的问题,或者它解决了你的问题?
setcolorder(dt1 <- df[order(-Date)][order(Tag1), .SD, by = Tag2], colnames(df))
dt1
# Tag1 Tag2 Date
# 1: 22 22 2008-07-25
# 2: 253 255 2000-06-15
# 3: 6219 252857 2002-09-06
# 4: 6219 6220 2000-06-30
# 5: 252862 252863 2002-09-06
# 6: 312812 252863 2003-09-05
# 7: 252864 252865 2002-09-06
# 8: 312786 251191 2003-09-03
df[,lapply(df, sort)]
# Tag1 Tag2 Date
# 1: 22 22 2000-06-15
# 2: 253 255 2000-06-30
# 3: 6219 6220 2002-09-06
# 4: 6219 251191 2002-09-06
# 5: 252862 252857 2002-09-06
# 6: 252864 252863 2003-09-03
# 7: 312786 252863 2003-09-05
# 8: 312812 252865 2008-07-25
DT[, asDate := as.Date(Date, format = "%m/%d/%Y")]
setkey(DT, asDate, Tag1, Tag2)
DT[, g2 := .GRP, Tag2]
setkey(DT, g2)
DT[, g1 := .GRP, Tag1]
setkey(DT, g1)
DT[, c("g1", "g2", "asDate") := NULL][]
Tag1 Tag2 Date
1: 252860 252861 9/6/2002
2: 252862 252863 9/6/2002
3: 312812 252863 9/5/2003
4: 252864 252865 9/6/2002
5: 252866 252867 9/6/2002
6: 252868 252869 9/6/2002
7: 252870 252871 9/6/2002
8: 318880 252871 10/8/2003
9: 318880 414547 9/29/2004
10: 252872 252873 9/6/2002
11: 252874 252875 9/6/2002
12: 252876 252877 9/6/2002
13: 252878 252879 9/6/2002
14: 252880 905593 9/6/2002
15: 252880 414611 10/5/2004
16: 252881 252882 9/6/2002
17: 252883 252884 9/6/2002
18: 252885 252886 9/10/2002
19: 252887 252888 9/10/2002
20: 311264 252888 7/15/2003
21: 252889 252890 9/10/2002
22: 252889 318904 10/15/2003
23: 252892 252893 9/10/2002
24: 318879 318878 10/8/2003
25: 318881 318882 10/8/2003
Tag1 Tag2 Date
a b
a c
b a
b c
c a
c b