【问题标题】:R: For each row, find the column-index of the column that has the highest valueR:对于每一行,找到具有最高值的列的列索引
【发布时间】:2019-07-14 10:29:15
【问题描述】:

我正在尝试获取所选列中具有最高值的列的索引。尝试使用dplyr 时,我的尝试没有给我正确的结果。

library(dplyr);library(magrittr)
DF1 <- data.frame(Factor1 = c(1,2,4),Factor2 = c(3,1,1),Factor3 = c(9,1,0)) %>% 
    mutate(max_ind = which.max(c(.$Factor1,.$Factor2,.$Factor3))) %>% print
          Factor1 Factor2 Factor3 max_ind
        1       1       3       9       7
        2       2       1       1       7
        3       4       1       0       7

错在哪里?为什么dplyr 会这样。我可能应该使用rowwise,但这似乎不是best way。在basetidyversedata.table 中是否想过如何做到这一点?

Edit-1(其他尝试)

有了 sapply,我得到了这个:

DF1 <- data.frame(Factor1 = c(1,2,4),Factor2 = c(3,1,1),Factor3 = c(9,1,0)) %>%
+   mutate(max_ind = which.max(c(Factor1,Factor2,Factor3)),
+          max_ind2 = sapply(X = ., function(x) which.max(c(x[Factor1],x[Factor2],x[Factor3])))) %>% print
  Factor1 Factor2 Factor3 max_ind max_ind2
1       1       3       9       7        4
2       2       1       1       7        1
3       4       1       0       7        1

但在这里我看到第一行是 4,而应该是 3。

编辑-2

我也在寻找一种解决方案,我们可以指定用于比较的列 (which.max)

编辑-3

所有basepurrr::mapdplyr::mutate 示例都有效。

#R>DF1 <- data.frame(Factor1 = c(1,2,4,1),Factor2 = c(3,1,1,6),Factor3 = c(9,1,0,4)) 
#R>DF1 %>% mutate(max_ind_purrr = pmap(.l = list(Factor1,Factor2,Factor3),~which.max(c(...)))) %>% print()
  Factor1 Factor2 Factor3 max_ind_purrr
1       1       3       9             3
2       2       1       1             1
3       4       1       0             1
4       1       6       4             2
#R>DF1 %>% mutate(max_ind_dplyr=max.col(DF1[,1:3]))
  Factor1 Factor2 Factor3 max_ind_dplyr
1       1       3       9             3
2       2       1       1             1
3       4       1       0             1
4       1       6       4             2
#R>DF1 <- transform(DF1,max_ind_base=apply(DF1[, c('Factor1','Factor2','Factor3')],1,which.max))%>% print
  Factor1 Factor2 Factor3 max_ind_base
1       1       3       9            3
2       2       1       1            1
3       4       1       0            1
4       1       6       4            2

【问题讨论】:

  • DF1$max_ind &lt;- max.col(DF1) ?
  • 这不完整。我应该能够指定应该用于比较的列。
  • @DavidArenburg Neat,不知道这是矢量化的,我已将其包含在我的答案中。
  • @Stat-R 如果需要可以指定。
  • @jay.sf 没关系。

标签: r dplyr data.table


【解决方案1】:

我认为您要求逐行比较以找到包含 该行的最大值的列索引。这就是为什么 sapply 不能正常工作的原因,默认情况下,它会向下查看列。 which.max 还处理向量 - 在您的情况下,您不想返回每个向量中的索引,因为它指的是 column 向量而不是 data.frame 的行。

这基本上就是max函数和pmax函数的区别。 which.max 的逐行版本是 max.col,因此您可以指定:

DF1 %>% mutate(max_ind=max.col(DF1))

然后您可以选择要指定的列:

# only considering columns 1 and 2
DF1 %>% mutate(max_ind=max.col(DF1[,1:2]))

【讨论】:

  • 虽然写得少,但我强烈建议明确地制定列名。否则,如果订单发生变化,它可能会产生一团糟,例如在一个大型项目中。
  • 请记住,max.col 总是将其输入强制转换为矩阵,因此它不适合数据帧。
【解决方案2】:

在基础 R 中你可以这样做:

DF1 <- transform(DF1, max_ind=apply(DF1, 1, which.max))

但是,正如 @DavidArenburg 在 cmets 中明智地指出的那样 - 实际上存在矢量化方法 max.col()

DF1 <- transform(DF1, max_ind=max.col(DF1))
#         Factor1 Factor2 Factor3 max_ind
# Factor1       1       3       9       3
# Factor2       2       1       1       1
# Factor3       4       1       0       1

要获得最大的指定列名,只需在子集上相应地执行此操作。

DF1 <- transform(DF1, max_ind_subset=max.col(DF1[c("Factor1", "Factor2")]))
#   Factor1 Factor2 Factor3 max_ind_subset
# 1       1       3       9              2
# 2       2       1       1              1
# 3       4       1       0              1

数据

DF1 <- structure(list(Factor1 = c(1, 2, 4), Factor2 = c(3, 1, 1), Factor3 = c(9, 
1, 0)), class = "data.frame", row.names = c(NA, -3L))

【讨论】:

  • 我认为 OP 想要列的最大 ind 而不是您在这里计算的行 - 碰巧两种情况下的结果都是相同的
  • @Chris 其实我正在寻找每一行的最大值列的索引
  • @Stat-R 是的,这就是我的意思。我认为这就是杰克的回答,而不是杰的回答,你同意吗?
  • @Stat-R,这是因为您的示例是对称的。例如,将其更改为 factor1=c(1,4,2) ,答案会有所不同。我认为您正在寻找杰克的答案,但我可能错了
  • @jay.sf 不确定该评论是针对我的吗?但是我同意您已编辑答案现在可以完成工作+1 :)
【解决方案3】:

purrr::pmap试试这个:

DF1 <-
  data.frame(
    Factor1 = c(1, 2, 4),
    Factor2 = c(3, 1, 1),
    Factor3 = c(9, 1, 0)
  ) %>%
  mutate(max_ind = pmap_int(list(Factor1, Factor2, Factor3), ~which.max(c(...))))

输出:

  Factor1 Factor2 Factor3 max_ind
1       1       3       9       3
2       2       1       1       1
3       4       1       0       1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 2020-10-14
    • 1970-01-01
    • 2018-01-10
    • 2019-10-11
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多