2012-10-21 27 views
3

我已經有了一個包含多個(數字)列的數據框,並且希望創建一個新的數據框,其列是原始的列。構建動態轉換語句

> df <- data.frame(cbind(id=LETTERS[1:10], 
wheat=c(123,234,345,456,678,987,876,654,432,321),barley=c(135,975,246,864,357,753,468,642,579,531))) 
> df 
    id wheat barley 
1 A 123 135 
2 B 234 975 
3 C 345 246 
4 D 456 864 
5 E 678 357 
6 F 987 753 
7 G 876 468 
8 H 654 642 
9 I 432 579 
10 J 321 531 
> rankeddf <- transform(df, wheat=rank(wheat), barley=rank(barley)) 
> rankeddf 
    id wheat barley 
1 A  1  1 
2 B  2  10 
3 C  4  2 
4 D  6  9 
5 E  8  3 
6 F 10  8 
7 G  9  4 
8 H  7  7 
9 I  5  6 
10 J  3  5 

事情是,列的數量和名稱不同。我有一個指定它們的向量:

cols <- c("wheat", "barley") 

我該如何構建transform聲明?或者甚至循環遍歷cols向量,在每次迭代中應用transform語句一次?我猜測答案將與evalevalq有關,但我還沒有把我的頭圍繞在他們身上。例如,

> rankeddf2 <- df 
> for (col in cols) {rankeddf2 <- transform(rankeddf2, evalq(paste(col,"=rank(",col,")",sep="")))} 
> rankeddf2 
    id wheat barley 
1 A 123 135 
2 B 234 975 
3 C 345 246 
4 D 456 864 
5 E 678 357 
6 F 987 753 
7 G 876 468 
8 H 654 642 
9 I 432 579 
10 J 321 531 

沒有辦法。

另外,是否有另一種方法呢?

回答

6

您可以通過使用lapplyrank()做到這一點:

as.data.frame(lapply(df[, cols], rank)) 
    wheat barley 
1  1  1 
2  2  10 
3  4  2 
4  6  9 
5  8  3 
6  10  8 
7  9  4 
8  7  7 
9  5  6 
10  3  5 

OK,所以在這個過程中,你失去了第一列,但是這很容易添加回:

data.frame(id=df[[1]], lapply(df[, cols], rank)) 
    id wheat barley 
1 A  1  1 
2 B  2  10 
3 C  4  2 
4 D  6  9 
5 E  8  3 
6 F 10  8 
7 G  9  4 
8 H  7  7 
9 I  5  6 
10 J  3  5 
+0

'taRifx :: japply'基本上是你的兩個步驟相結合。我還沒有徹底調試過,所以如果你得到奇怪的結果,請讓我知道。 –

+0

這給出了我想要的,併爲我帶來了一點燈泡時刻:我想我現在確實意識到數據框是列的列表。 – lpryor

4

我喜歡將transform()和相關的with()within()作爲語法糖,它們交互式地在頂層有用,但頗爲有用常子集化,並通過'['()'[<-'()等更換更易於使用的工作,比如這個:

> df2 <- df ## copy 
> df2[, cols] <- apply(df[, cols], 2, rank) 
> df2 
    id wheat barley 
1 A  1  1 
2 B  2  10 
3 C  4  2 
4 D  6  9 
5 E  8  3 
6 F 10  8 
7 G  9  4 
8 H  7  7 
9 I  5  6 
10 J  3  5 

'['()'[<-'()已經做你想做的,所以你在試圖迫使transform()做一些事情,已經實現多更容易使用子集和替換功能。

+0

RHS可能是'sapply(df [cols],rank)',並且不會遇到與dataframe對象一起使用的任何不適宜的「特徵」。 –

+0

認識到變換等主要以交互方式而非編程方式有用是有幫助的。 – lpryor