我有以下对象:
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的值而更改。
我现在要实现以下目标:
df
中最后三列中哪一列的值最高,并将其作为值存储在新列中(值应为1,2或3,具体取决于是否最高的值是这些变量的第一个,第二个或第三个)。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时,我可能会尝试通过按列名来使事情变得过于复杂。
答案 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