从具有更改名称的列中计算按行最大值

时间:2019-08-05 17:59:30

标签: r tidyverse

我有以下对象:

s1 = "1_1_1_1_1"
s2 = "2_1_1_1_1"
s3 = "3_1_1_1_1"

请注意,在另一个示例中,s1,s2,s3的值可以更改。

然后我得到以下数据框:

set.seed(666)
df = data.frame(draw = c(1,2,3,4,1,2,3,4,1,2,3,4),
                resp = c(1,1,1,1,2,2,2,2,3,3,3,3),
                "1_1_1_1_1" = runif(12),
                "2_1_1_1_1" = runif(12),
                "3_1_1_1_1" = runif(12)).

请注意,may数据帧的列名称将根据s1,s2,s3的值而更改。

我现在要实现以下目标:

  1. 我想找出df中最后三列中哪一列的值最高,并将其作为值存储在新列中(值应为1,2或3,具体取决于是否最高的值是这些变量的第一个,第二个或第三个)。
  2. 现在我知道哪个值是最高的每行,我想按列resp分组/汇总结果,并计算我的最大值是1、2还是3的频率3。

所以1.的结果应该是:

draw    resp    1_1_1_1_1    2_1_1_1_1    3_1_1_1_1    max
1       1       0.774        0.095        0.806        3
2       1       0.197        0.142        0.266        3
...

从2得到的结果应该是:

resp    first_max    second_max    third_max
1       1            1             2
2       2            1             1
3       1            2             1

我的问题是tidyverse的行函数已被弃用,我不知道如何通过外部存储的列名(在s1,s2,s3中)动态寻址tidyverse管道中的列。最后一点:实际上,当我感兴趣的列的位置始终位于列位置3:5时,我可能会尝试通过按列名来使事情变得过于复杂。

2 个答案:

答案 0 :(得分:3)

这里是获得想要的东西的一种方法。对于稍微不同的格式,可以使用count而不是table,但这与您的预期输出匹配。希望这会有所帮助!

library(dplyr)

df %>%
  mutate(max_val = max.col(select(., starts_with("X")))) %>%
  select(resp, max_val) %>%
  table()

    max_val
resp 1 2 3
   1 1 1 2
   2 2 1 1
   3 1 2 1

或者,您可以这样做:

df %>%
  mutate(max_val = max.col(.[3:5])) %>%
  count(resp, max_val) %>%
  mutate(max_val = paste0("max_", max_val)) %>%
  spread(value = n, key = max_val)

   resp max_1 max_2 max_3
  <dbl> <int> <int> <int>
1     1     1     1     2
2     2     2     1     1
3     3     1     2     1

答案 1 :(得分:1)

使用pmap(行迭代)计算最大值

max_cols <- pmap_dbl(unname(df),function(x,y,...){
    vals <- unlist(list(...))
    return(which(vals == max(vals)))
})


result <- df %>% add_column(max = max_cols)

> result
   draw resp X1_1_1_1_1 X2_1_1_1_1  X3_1_1_1_1 max
1     1    1  0.4551478 0.70061232 0.618439890   2
2     2    1  0.3667764 0.26670969 0.024742605   1
3     3    1  0.6806912 0.03233215 0.004014758   1
4     4    1  0.9117449 0.42926492 0.885247456   1
5     1    2  0.1886954 0.34189707 0.985054492   3
6     2    2  0.5569398 0.78043504 0.100714130   2
7     3    2  0.9791164 0.92823982 0.676584495   1
8     4    2  0.9174654 0.74627116 0.485582287   1
9     1    3  0.3681890 0.69622331 0.672346875   2
10    2    3  0.5510356 0.99651637 0.482430518   2
11    3    3  0.4283281 0.12832611 0.018095649   1
12    4    3  0.6168436 0.64381995 0.655178701   3

重塑数据框。

reshape2::dcast(result,resp~max,fun.aggregate = length,value.var = "max")
  resp 1 2 3
1    1 1 1 2
2    2 2 1 1
3    3 1 2 1