2011-07-09 45 views
4

我在order周圍寫了這個小小的包裝,但我擔心我的實現是跛腳。我蜷縮在角落裏,等待着R的神命令或算法的效率要刺我的人體工程學鍵盤:-(有沒有更簡單的方法來重新排列數據的列值?

set.seed(1001) 

height <- rnorm(6, mean = 1, sd = 0.2) 
weight <- rnorm(6, mean = 100, sd = 15) 
id  <- 1:6 

dd <- data.frame(id, height, weight) 

# Here's the function I came up with 
ReorderDataByColumn <- function(x, column) { 
    ordered.indices <- order(x[ ,paste(column)]) 

    return(x[ordered.indices, ]) 
} 

#And here are its results 
> ReorderDataByColumn(dd, column = "height") 
    id height weight 
4 4 0.4986928 76.09430 
5 5 0.8885377 104.53967 
3 3 0.9629449 86.38809 
2 2 0.9644905 90.65584 
6 6 0.9712881 124.51589 
1 1 1.4377296 116.37253 

> ReorderDataByColumn(dd, column = "weight") 
    id height weight 
4 4 0.4986928 76.09430 
3 3 0.9629449 86.38809 
2 2 0.9644905 90.65584 
5 5 0.8885377 104.53967 
1 1 1.4377296 116.37253 
6 6 0.9712881 124.51589 
+0

我現在很困惑。在這種情況下'paste()'實際上做了什麼? –

+0

+1對於問我想知道我自己的東西... – joran

+0

請參閱這裏的答案几個更好的選擇:http://stackoverflow.com/q/1296646/210673 – Aaron

回答

4

我不進擊打業務形成很好的問題。我以爲代碼是可讀的,明智的。如果你想它收緊一點,你可以通過拖放粘貼()操作「[」和內部創建索引「[」:

ReorderDataByColumn2 <- function(x, column) { 
    return(x[ order(x[[column]]), ]) 
} 

編輯:添加哈德利的建議(除了我認爲你也需要do.call):

ReorderDataByColumn2 <- function(x, column, desc=FALSE) { 
    return(
     x[ do.call(order, x[ , column, drop=FALSE ] ), ] 
    ) } 

您可以添加,如果你想要一些錯誤檢查:

ReorderDataByColumn2 <- function(x, column) { 
    if(column %in% names(x)){return(x[ order(x[[column]]), ]) 
    }else{ cat("Column ", column, "not in dataframe ", deparse(substitute(x))) } 
} 
+0

我從來不知道雙括號「[[」like那。我認爲這只是列表的索引表示法。但是它也可以用一個字符串來評估參數嗎? – briandk

+0

這不是真的簡寫......它是最初的方法。 「[[」評估它的論點。它的缺點是它只接受一個參數,所以如果你通過多個列排序,這將失敗。 –

+0

如果你想索引多個列,你可以做'x [,column,drop = F]' – hadley

2

見plyr的安排功能:

library(plyr) 
arrange(mtcars, cyl) 
arrange(mtcars, desc(cyl)) 
arrange(mtcars, vs, am) 

函數的定義很簡單:

arrange <- function (df, ...) { 
    ord <- eval(substitute(order(...)), df, parent.frame()) 
    unrowname(df[ord, ]) 
} 

它的工作原理與基於R的subset非常相似。

相關問題