如何用for loop替代重复代码,对zipid1-zipid30的died变量求和?
嘿,这种重复写几十行几乎一样代码的事儿谁都烦!别担心,用for循环完全能替代,甚至还有更符合dplyr风格的简洁方法,我给你详细说说:
方法一:使用for循环实现
假设你的数据框名为df,包含died列以及zipid1到zipid30这30个标识列(比如用1/0标记是否属于对应区域),可以这样写:
library(dplyr) # 初始化一个空数据框,用来存储每个zipid的求和结果 sum_results <- data.frame(zipid = character(), died_sum = integer(), stringsAsFactors = FALSE) # 循环遍历1到30,处理每个zipid列 for (i in 1:30) { # 动态构造当前zipid的列名 zip_col_name <- paste0("zipid", i) # 筛选出当前zipid对应的行,对died求和(na.rm=TRUE处理缺失值) current_died_sum <- df %>% filter(.data[[zip_col_name]] == 1) %>% # 根据你的实际数据调整筛选条件 summarize(died_sum = sum(died, na.rm = TRUE)) %>% pull(died_sum) # 将结果添加到结果数据框中 sum_results <- sum_results %>% add_row(zipid = zip_col_name, died_sum = current_died_sum) }
*注意:*如果你的zipid列不是1/0标识(比如直接存储区域编码),需要把filter里的条件改成符合你数据逻辑的判断,比如filter(zipid == i)(如果是单独的zipid列而不是多列的话)。
方法二:更简洁的tidyverse长格式处理(推荐)
其实用dplyr配合tidyr的话,完全可以不用循环,把宽格式数据转成长格式后分组求和,代码更简洁也更易维护:
library(dplyr) library(tidyr) # 把宽格式转成长格式:将zipid1-zipid30列合并为zipid列,标记是否属于该区域 df_long <- df %>% pivot_longer( cols = starts_with("zipid"), # 匹配所有以zipid开头的列 names_to = "zipid", values_to = "is_in_zip" ) %>% filter(is_in_zip == 1) # 筛选属于对应zip的行 # 按zipid分组,对died求和 sum_results <- df_long %>% group_by(zipid) %>% summarize(died_sum = sum(died, na.rm = TRUE)) %>% ungroup()
这种方法的好处是:哪怕以后zipid的数量变成50个或者10个,你都不用修改代码,只要保证列名以zipid开头就行,完全避免了重复代码的问题。
内容的提问来源于stack exchange,提问作者mandy
相关产品推荐
相关产品推荐

