2017-02-23 73 views
0

數據幀的R - 對於每一行,返回相匹配的值

rd2 <- data.frame(x = sample(1:100, 20), y = sample(1:100, 20), z 
    sample(1:100, 20)) 

    # function I found in stackoverflow for finding the second largest value 
    maxN <- function(x, N = 2){ 
     len <- length(x) 
     if(N > len){ 
     warning('N greater than length(x). Setting N = length(x)') 
     N <- length(x) 
     } 
     sort(x,partial = len - N+1)[len - N+1] 
    } 

    # indexing values 
    rd2[, "axis1n"] <- apply(rd2[1:3], 1, function (x) max(x)) 
    rd2[, "axis2n"] <- apply(rd2[1:3], 1, function (x) maxN(x)) 

    rd2 
     x y z axis1n axis2n 
    1 56 63 84  84  63 
    2 50 45 13  50  45 
    3 79 21 43  79  43 
    4 33 46 33  46  33 
    5 46 26 12  46  26 
    6 55 47 11  55  47 
    7 85 76 85  85  85 
    8 43 56 48  56  48 
    9 17 67 92  92  67 
    10 37 43 59  59  43 
    11 21 89 27  89  27 
    12 57 44 25  57  44 
    13 27 20 88  88  27 
    14 63 62 44  63  62 
    15 80 14 46  80  46 
    16 88 54 54  88  54 
    17 16 97 65  97  65 
    18 48 83 77  83  77 
    19 77 17 53  77  53 
    20 47 64 70  70  64 

你好colnames,

我需要兩列添加到該數據幀,其中:

AXIS1: 每個行,與axis1n中的值匹配的列的列名稱(最大值)

axis2: 對於每行,列匹配的列名稱在axis2n中的值(第二大)

使用max.col獲取最大值的列名很容易,但是我需要一種可以爲許多不同索引值(例如第二大值或簡單列表)重現的方法的數字給予..

希望我有道理..請幫助!

謝謝!

+0

因此對於第1行,axis1將爲「z」,axis2爲「y」 – user5813583

+0

我需要通過使用任何給定的整數/整數列表來做到這一點... – user5813583

回答

1

這沒有經過測試,但也許你可以引入另一個參數給現有的功能,你可以控制功能達到最大值的「遠」。

另請注意,我刪除了N - 這是不需要用戶控制的東西。如果你設置了reachback = 0,你會得到最大的。 reachback = 1將輸出第二個到最大值,等等......

我也禁用了前N的截斷 - 如果你超越,你會得到一個錯誤。隨意保留原樣或將error更改爲warning並添加reachback <- len一行。

set.seed(357) 
rd2 <- data.frame(x = sample(1:100, 20), y = sample(1:100, 20), z = sample(1:100, 20)) 

# function I found in stackoverflow for finding the second largest value 
maxN <- function(x, reachback = 0){ 
    # reachback = 0 is maximum, 1 is second to last, 2 is third to last and so on... 
    len <- length(x) 
    if(reachback > len){ 
    error('You can not overreach the number of variables.') 
    } 
    names(sort(x, decreasing = TRUE)[1 + reachback]) 
} 

# indexing values 
# rd2[, "axis1n"] <- apply(rd2[1:3], 1, function (x) max(x)) 
rd2[, "axis_max"] <- apply(rd2[1:3], 1, function (x) maxN(x, reachback = 0)) 
rd2[, "axis_2nd"] <- apply(rd2[1:3], 1, function (x) maxN(x, reachback = 1)) 
rd2[, "axis_3rd"] <- apply(rd2[1:3], 1, function (x) maxN(x, reachback = 2)) 
rd2 

    x y z axis_max axis_2nd axis_3rd 
1 11 19 18  y  z  x 
2 6 46 4  y  x  z 
3 28 36 64  z  y  x 
4 22 5 40  z  x  y 
5 63 68 48  y  x  z 
6 45 66 26  y  x  z 
7 88 35 50  x  z  y 
8 70 15 87  z  x  y 
9 72 48 7  x  y  z 
10 91 89 46  x  y  z 
11 57 98 73  y  z  x 
12 47 83 36  y  x  z 
13 41 25 35  x  z  y 
14 20 44 33  y  z  x 
15 51 50 17  x  y  z 
16 15 69 6  y  x  z 
17 27 59 8  y  x  z 
18 75 22 59  x  z  y 
19 90 70 30  x  y  z 
20 35 64 20  y  x  z 
+0

嗨,感謝您的提示!雖然我真的需要幫助獲取每行匹配值的列名!任何想法? :D – user5813583

+0

@ user5813583啊,只需一秒鐘。 –

+0

@ user5813583看到我的編輯。 –

0

以下是在列名上使用order的方法。

# get the column names 
cols <- names(rd2) 

cbind(rd2, 
     setNames(data.frame(t(apply(rd2, 1, 
            function(i) cols[order(i, decreasing=TRUE)]))), 
        paste0("max", 1:3))) 

返回

x y z max1 max2 max3 
1 11 19 18 y z x 
2 6 46 4 y x z 
3 28 36 64 z y x 
4 22 5 40 z x y 
5 63 68 48 y x z 
6 45 66 26 y x z 
... 

這裏,cols[order(i, decreasing=TRUE)]返回排序從最高到最低的列名。 apply將此應用於data.frame中的每一行。 t將此轉換,data.frame將此轉換爲data.frame,而setNames將名稱添加到data.frame。這與cbind合併爲原始數據框。

您可以通過將[添加到order(i, decreasing=TRUE)(如order(i, decreasing=TRUE)[1:2])來更改列出的列數以獲得前2列名稱。您也可以通過將paste0("max", 1:3)更改爲所需的值來更改列名稱。