R语言如何统计变量取值模式及共同出现的频次
实现方法
处理思路
你需要的统计逻辑可以拆解为三步:
- 对a、b、c、d四个变量逐个作为目标变量,筛选该变量取值为1的所有行
- 对筛选出的行,计算a-d四个变量中取值为1的总个数(即目标变量为1,加上其余变量中1的个数)
- 按总个数分组,对n列求和,最后整理为宽表格式即可
完全可以用plyr包的ddply实现,也可以用tidyverse系列函数实现,两种方法如下:
前置准备
你给出的数据集里a-d都是因子类型,我们直接判断取值是否为字符"1"即可,无需额外转换类型,先加载需要的包:
# 用tidyverse实现的话加载 library(tidyverse) # 用ddply实现的话加载 library(plyr)
方法1:tidyverse实现
# 逐个处理每个目标变量 res <- purrr::map_dfr(set_names(c("a","b","c","d")), function(target_var) { df %>% # 筛选目标变量为1的行 filter(!!sym(target_var) == "1") %>% # 计算当前行a-d中取值为1的总个数 mutate(k = rowSums(select(., a, b, c, d) == "1")) %>% group_by(k) %>% summarise(sum_n = sum(n), .groups = "drop") }, .id = "var") %>% # 转为你需要的宽格式,缺失值补0 pivot_wider(names_from = k, values_from = sum_n, values_fill = 0) # 调整为你期望的输出格式 res <- res %>% mutate(var = toupper(var)) %>% column_to_rownames("var")
输出结果和你给出的期望格式完全一致。
方法2:ddply实现
res_ddply <- plyr::ldply(set_names(c("a","b","c","d")), function(target_var) { # 筛选目标变量为1的行 sub_df <- df[df[[target_var]] == "1", ] # 处理目标变量没有取1的情况(比如示例中的a变量) if(nrow(sub_df) == 0) { return(data.frame(`1` = 0, `2` = 0, `3` = 0, check.names = FALSE)) } # 计算每行1的总个数 sub_df$k <- rowSums(sub_df[, c("a","b","c","d")] == "1") # 用ddply分组求和后转宽表 plyr::ddply(sub_df, .(k), summarise, sum_n = sum(n)) %>% pivot_wider(names_from = k, values_from = sum_n, values_fill = 0) }, .id = "var") %>% mutate(var = toupper(var)) %>% column_to_rownames("var")
内容的提问来源于stack exchange,提问作者Bcohen
相关产品推荐
相关产品推荐

