2013-01-11 43 views
2

我正在嘗試重新排列包含大約250,000行和7列的data.frame。在data.frame的頂部,我想要的行是列2包含最低值和最高列7的那些行,但是會包含從最低到最高值的列序列:2,5,1,4,6, 3,7(因此第5列將具有第二低的值等)。通過多列置換對數據幀中的行進行重新排序

一旦找到與此序列匹配的任何行,它就會繼續查找列值從2,5,1,4,6然後2,5,1,4的最低到最高的行依此類推,直到只有列2是最低的行和其他列值被隨機分配。任何沒有列2作爲最低值的行都將被忽略,並在排序後的行之下排序。我掙扎着拿出任何可行的解決我的問題 - 我可以提供類似的數據,我有工作的方面做的最好的是這樣的:

df<-data.frame(matrix(rnorm(70000), nrow=10000)) 
df<-abs(df) 

如果任何人有任何想法,我所有耳朵。 謝謝!

+1

你的問題描述很難理解。也許你可以創建一個小例子(6 x 4?),你可以在其中顯示出發點,然後顯示程序的預期結果? – bdemarest

回答

2

既然你有統一的類型(數字)的一個相當大的數據集,我會建議使用矩陣不是一個data.frame

tt <- abs(matrix(rnorm(70000), nrow=10000)) 

你必須要匹配對

desiredOrder <- c(2,5,1,4,6,3,7) 
期望的順序

你需要找到你的每一行的順序。我認爲在這裏最簡單的方法是確保每個行都有一個元素。我會建議這樣的事情。

orders <- lapply(apply(tt, 1, function(x) list(order(x))), unlist) 

然後,您將需要經歷(從desiredOrder[seq_len(7)]desiredOrder[seq_len(1)]測試時,特定行的順序所需的子集等於所需的順序所需的子集。(我想的sapply一些組合whichall

一旦你已經確定了所有符合您要求的結果是,行,你可以使用setdiff找到無與倫比的,然後使用該new order向量重新排序tt

+0

謝謝你的回答。然而,在使用sapply時,我遇到了問題,哪些和哪些功能。看起來行已經按照我想要的順序排列,但是在某些時候它看起來是按列順序排列而不是按照期望的列順序排列的。顯然,我做錯了一些我無法解決的問題,當你提出這些功能時,你能否給我一個進一步的想法?非常感謝 – Chris

0

一種可能的方法是對列中值的排序進行加權。這將是像排名迴歸。 250K行的7列不是那麼大。對於那些你想低值有更高的權重,你可以從NROW(dfrm)減去排名。如果你想擴展跨列排序方案的wieighting則僅僅指剛通過加權矢量乘以:說C(1。6,3,0 .3,.6 1)

dmat <- matrix(sample(20, 20*7, repl=TRUE), 20, 7) 
dfrm <- as.data.frame(dmat) 

dfrm$wt <- sapply(dfrm[ c(2,5,1,4,6,3,7)] , rank); dfrm 
dfrm$wt[,1:3] <- rep(NROW(dfrm),3) - dfrm$wt[ , 1:3] 
dfrm$wt <- dfrm$wt*rep(c(1, .6, .3, 0, .3, .6, 1), each=NROW(dfrm)) 
dfrm[ order(apply(dfrm$wt, 1, FUN=sum), decreasing=TRUE) , ] 

這確實不要強迫V2的最低值爲第一,因爲你暗示了一個多重標準。如果這不符合你的想象,你仍然有能力重新加重。

0

像這樣:

dat <- as.matrix(df) 
rnk <- t(apply(dat, 1, rank)) 
desiredRank <- order(c(2,5,1,4,6,3,7)) 
rnk.match <- rnk == matrix(desiredRank, nrow(rnk), ncol(rnk), byrow = TRUE) 
match.score <- apply(rnk.match, 1, match, x = FALSE) - 1 
match.score[is.na(match.score)] <- ncol(dat) 
out <- dat[order(match.score, decreasing = TRUE), ] 

head(out) 
#   X1   X2  X3  X4  X5  X6  X7 
#[1,] 0.7740246 0.19692680 1.5665696 0.9623104 0.2882492 1.367786 1.8644204 
#[2,] 0.5895921 0.00498982 1.7143083 1.2698382 0.1776051 2.494149 1.4216615 
#[3,] 0.1981111 0.11379934 1.0379619 0.2130251 0.1660568 1.227547 0.9248101 
#[4,] 0.7507257 0.23353923 1.6502192 1.2232615 0.7497352 2.032547 1.4409475 
#[5,] 0.5418513 0.06987903 1.8882399 0.6923557 0.3681018 2.172043 1.2215323 
#[6,] 0.1731943 0.01088604 0.6878847 0.2450998 0.0125614 1.197478 0.3087192 

在這個例子中,第一行相匹配的全秩序列;下一行匹配序列的第一個五個等級:

head(match.score[order(match.score, decreasing = TRUE)]) 
# [1] 7 5 5 5 5 5 
0

您可以使用這一事實order()返回指數來排序,
這是你試圖匹配

什麼
For example if we apply `order` twice to each row of 
    [1,] 23 17 118 57 20 66 137 
    [2,] 56 42 52 66 47 8 29 
    [3,] 35 5 76 35 29 217 89 

We would get 
    [1,] 2 5 1 4 6 3 7 
    [2,] 6 7 2 5 3 1 4 
    [3,] 2 5 1 4 3 7 6 

然後你只需要檢查哪些行匹配你正在尋找。



存在實現這幾種方法,下面是一個例子,在這裏我們創建
邏輯矩陣, comparisons,表示一排
的每個元素是否處於「正確」的位置,如圖由 expectedOrder指示。

然後,我們通過「正確的列」中有多少個元素
來訂購原始行。 (當然使用這個短語)

# assuming mydf is your data frame or matrix 

# the expected order of the columns 
expectedOrder <- c(2,5,1,4,6,3,7) 

# apply the order function twice. 
ordering <- apply(mydf, 1, function(r) order(r)) 

# Recall that the output of apply is transposed relative to the input. 
# We make use of this along with the recycling of vectors for the comparison 
comparisons <- ordering == expectedOrder 

# find all rows with at least matches to 2,5,1,4 
topRows <- which(colSums(comparisons[1:4, ])==4) 

# reorder the indecies based on the total number of matches in comparisons 
# ie: first all 7-matches, then 5-matches, then 4-matches 
topRows <- topRows[order(colSums(comparisons[,topRows]), decreasing=TRUE)] 

# reorder the dataframe (or matrix) 
mydf.ordered <- 
    rbind(mydf[topRows, ], 
     mydf[-topRows,]) 

head(mydf.ordered) 
# X1 X2 X3 X4 X5 X6 X7 
# 23 17 118 57 20 66 137 
# 39 21 102 50 24 53 163 
# 80 6 159 116 44 139 248 
# 131 5 185 132 128 147 202 
# 35 18 75 40 33 67 151 
# 61 14 157 82 57 105 355 
+0

由於您的排序只包含至少匹配前四行的行,因此您並未完全回答該問題。也要小心使用負面索引編程。如果'topRows'爲空,則'rbind(mydf [topRows,],mydf [-topRows,])'也將爲空。 – flodel

相關問題