2016-08-10 143 views
10

這裏的數據表是一個短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/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 

我想通過3列升序排序data.table:Tag1中,與Tag2和日期。 我測試:

> test <- DT[order(Tag1, Tag2, Date)] 
> test 
    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 

然而,我想如下排序的data.table:

> test 
     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: 312812 252863 2003-09-05 
    7: 252864 252865 2002-09-06 
    8: 312786 251191 2003-09-03 

特別地,對於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")) 

這裏是預期的結果(即,data.table 「後」)。特別地,data.table「後」應該尊重兩個條件:

1)行由日期升序排序

2)Tag1中或Tag1中重複的值低於一個設置其他(最終不需要按升序排列)

Tag1和Tag2的所有重複值均爲黃色。

enter image description here

+1

那麼你可能需要打破'order'。即'DT [,lapply(DT,sort)]' – akrun

+0

@Sathish這是一個評論,而不是一個答案。這就是我沒有發佈的原因。 – akrun

+0

您需要使用哪種數據來進行這種分組/排序? – HubertL

回答

6

舊秩序

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 

評論中的@akrun解決方案干擾了數據的結構。這是比較。看看#4:6219應該有252857代替251191

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

有沒有可能保留所有data.table列,而不是隻有三列「Tag1,」Tag2「和」Date「與函數setcolorder?例如,我有一個data.table與三列」Tag1, 「Tag2」和「Date」等欄目。 – Nell

+0

爲什麼不按日期順序排序,當第4行(data.table舊訂單)的日期替換爲第3行的日期(即2002-09-06 而不是2000-06-30 at第3行和2000-06-30而不是2002-09-06在第4行? – Nell

+0

例如:DT < - data.table(Tag1 = c(22,253,6219,6219,252862,252864,312786,312812 ), Tag2 = c(22,255,6220,252857,252863,252865,251191,252863), aa = c(1,5,9,6,8,1,1,3), Date = as.Date (如。字符(c(「7/25/2008」,「6/15/2000」,「9/6/2002」,「6/30/2000」,「9/6/2002」,「9/6/2002 「),」9/3/2003「,」9/5/2003「)),format =」%m /%d /%Y「)) setcolorder(test < - DT [order(Tag1,Tag2,Date) ] [,.SD,by = Tag2],colnames(DT))'。在這種情況下,日期未按順序排序(第3行和第4行按此新訂單) – Nell

2

例子中的數據已經排序所以這裏是無序爲了說明更改排序順序縮短版。

> 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 

使用order以特定的排序順序創建新的data.table。訂單功能採用單個字段或多個字段以指定的順序進行排序。

# sorts first by Tag1 then by Tag2 and finally by Date (in ascending order) 
> DT2 <- DT[order(Tag1, Tag2, Date)] 
> DT2 

    Tag1 Tag2  Date 
1: 22 1 2010-01-01 
2: 22 2 2000-02-02 
3: 22 2 2003-03-03 
4: 253 255 2000-04-04 

要重新排列data.table到位,請使用setorder函數。

setorder(DT,Tag1中,與Tag2,日期)

如果想按降序然後才能使用-前綴的字段名稱進行排序。

> DT[order(Tag1, Tag2, -Date)] 
> setorder(DT, Tag1, Tag2, -Date) 
+0

非常感謝JasonM1的回答。我的原始數據表就像我的例子,即按照排序順序。 – Nell

1

在一個更新的問題,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 
+0

@Nell我幾天前添加了這個答案 - 據我所知可以完全回答你的問題。是否有這個答案不適合你的問題,還是它解決了你的問題? – dww