在R中按年份与trt分组实现cover列排名:for循环及lapply方案
按年份与处理组分组对cover列排名的实现方法
首先给出数据定义:
df1 <- data.frame(year = c("2013", "2013", "2013", "2013", "2013","2013"), site = c("a", "a", "a", "a", "a", "a"), trt = c("x", "y", "x", "y", "x", "y"), cover = c(2, 5, 1,20,50,12)) df2 <- data.frame(year = c("2014", "2014", "2014", "2014", "2014","2014"), site = c("a", "a", "a", "a", "a", "a"), trt = c("x", "y", "x", "y", "x", "y"), cover = c(1, 3, 1,24,32,12)) df3 <- data.frame(year = c("2015", "2015", "2015", "2015", "2015","2015"), site = c("a", "a", "a", "a", "a", "a"), trt = c("x", "y", "z", "z", "x", "y"), cover = c(2, 5, 1,2,11,32)) df <- rbind(df1, df2, df3)
原有的按年份单独排名的for循环代码:
v1 <- unique(df$year) lst <- list() for (i in seq_along(v1)) { lst[[i]] <- df |> filter(year == v1[i]) |> mutate(rank = dense_rank(desc(cover))) }
1. 使用for循环实现按年份+处理组分组排名
核心是先获取所有唯一的year与trt组合,再针对每个组合过滤数据并计算排名:
# 获取所有唯一的(year, trt)分组组合 groups <- unique(df[, c("year", "trt")]) lst <- list() for (i in seq_len(nrow(groups))) { # 提取当前分组的年份和处理组 current_year <- groups$year[i] current_trt <- groups$trt[i] # 过滤对应分组的数据,计算组内排名 lst[[i]] <- df |> filter(year == current_year, trt == current_trt) |> mutate(rank = dense_rank(desc(cover))) } # 可选:将列表中的数据框合并为一个完整数据框 result_for <- do.call(rbind, lst)
2. 使用lapply函数实现按年份+处理组分组排名
方法一:基于分组组合的lapply实现
直接对groups的每一行进行处理,逻辑和for循环一致:
groups <- unique(df[, c("year", "trt")]) lst_lapply <- lapply(seq_len(nrow(groups)), function(i) { df |> filter(year == groups$year[i], trt == groups$trt[i]) |> mutate(rank = dense_rank(desc(cover))) }) # 合并结果 result_lapply1 <- do.call(rbind, lst_lapply)
方法二:基于split拆分数据的lapply实现
先用split将数据按year和trt拆分为子数据框列表,再对每个子框添加排名:
# 按year和trt拆分数据 split_df <- split(df, list(df$year, df$trt)) # 过滤掉空分组(如果有的话) split_df <- split_df[sapply(split_df, nrow) > 0] # 对每个子数据框计算组内排名 lst_lapply2 <- lapply(split_df, function(sub_df) { sub_df |> mutate(rank = dense_rank(desc(cover))) }) # 合并结果 result_lapply2 <- do.call(rbind, lst_lapply2)
内容的提问来源于stack exchange,提问作者Anh
相关产品推荐
相关产品推荐

