在for循环中使用slice_max提取列TOP3值时遇报错求助
解决dplyr中slice_max循环调用的报错问题
问题场景
现有如下数据框,需要为每一列生成包含该列前三大值的新数据框:
probUnweighted <- data.frame( Sample1 = c(0.9, 0.2, 0.03, 0.1, 0.5, 0.09), Sample2 = c(0.045, 0.11, 0.006, 0.0036, 0.005, 0.025), Sample3 = c(0.05, 0.21, 0.06, 0.0067, 0.0105, 0.1025) )
尝试用for循环实现,但slice_max抛出如下错误:
library(dplyr); library(tibble); library(tidyr) for (i in names(probUnweighted)){ assign(paste0("df_",i), probUnweighted %>% select(i) %>% slice_max(order_by = i, n = 3) ) }
报错信息:
Error in `slice_max()`: ! Can't compute indices. Caused by error: ! `order_by` must have size 6, not size 1.
错误原因
slice_max的order_by参数需要传入列引用或数值向量,但直接传入字符串i时,dplyr不会自动将其解析为对应列,而是把它当成长度为1的字符值,无法匹配数据框的6行长度,因此报错。
解决方案
方法1:使用.data代词解析字符串列名
修改slice_max中的order_by参数,用.data[[i]]来引用对应列的数值向量:
library(dplyr) for (i in names(probUnweighted)){ assign(paste0("df_",i), probUnweighted %>% select(i) %>% slice_max(order_by = .data[[i]], n = 3) ) }
方法2:改用列表存储结果(更推荐)
直接创建多个全局变量会污染环境,更规范的做法是将所有结果存储在一个列表中:
top3_list <- lapply(names(probUnweighted), function(col) { probUnweighted %>% select(all_of(col)) %>% slice_max(order_by = .data[[col]], n = 3) }) names(top3_list) <- paste0("df_", names(probUnweighted)) # 调用单个结果示例:top3_list$df_Sample1
方法3:用tidy风格一次性处理所有列
无需循环,通过重塑数据框完成批量筛选:
probUnweighted %>% pivot_longer(everything(), names_to = "Sample", values_to = "Value") %>% group_by(Sample) %>% slice_max(Value, n = 3) %>% pivot_wider(names_from = "Sample", values_from = "Value")
该方法会生成一个包含所有列前三大值的数据框,每行对应一个排名。
内容的提问来源于stack exchange,提问作者Chris Stantis
相关产品推荐
相关产品推荐

