【问题标题】:r - for each row, return colnames that matches a valuer - 对于每一行,返回与值匹配的列名
【发布时间】:2017-02-23 22:57:48
【问题描述】:

数据框

    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

你好,

我需要向这个数据框添加两列,其中:

轴 1: 对于每一行,与axis1n中的值匹配的列的列名(最大值)

轴2: 对于每一行,与axis2n中的值匹配的列的列名(第二大)

使用 max.col 可以轻松获取最大值的列名,但我需要一种可以为许多不同的索引值重现的方法,例如第二大值或给定的数字列表..

希望我说得通。请帮忙!

谢谢!!

【问题讨论】:

  • 所以对于第 1 行,axis1 将是“z”,axis2 将是“y”
  • 我需要能够通过使用任何给定的整数/整数列表来做到这一点......

标签: r dataframe match


【解决方案1】:

这未经测试,但也许您可以在现有函数中引入另一个参数,您可以在其中控制函数从最大值“回退”多远。

另外请注意,我已经删除了N - 这是不需要由用户控制的东西。如果您设置reachback = 0,您将获得最大值。 reachback = 1 将输出秒到最大值等等...

我还禁用了前 N 的截断 - 如果您超出范围,则会收到错误消息。随意保留原样或将error 更改为warning 并添加reachback &lt;- 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

【讨论】:

  • 您好,感谢您的提示!虽然我真的需要帮助来获取每行匹配值的列名!有什么想法吗? :D
  • @user5813583 啊,等一下。
【解决方案2】:

这是在列名上使用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 的原始data.frame 组合在一起。

您可以通过将 [ 添加到 order(i, decreasing=TRUE) 来更改列出的列数,例如 order(i, decreasing=TRUE)[1:2] 以获得前 2 个列名称。您还可以通过将paste0("max", 1:3) 更改为您想要的值来更改列名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-06
    • 2018-01-03
    • 2020-12-16
    • 1970-01-01
    • 2021-03-27
    相关资源
    最近更新 更多