R语言:如何基于df1按zip code统计type计数生成df2?
问题描述
现有如下结构的df1:
| state | zip code | type |
|---|---|---|
| NC | 00001 | person |
| NC | 00001 | property |
| NC | 00000 | person |
| NC | 00001 | property |
需要生成df2,每个zip code对应一条记录,person和property列分别统计df1中对应zip code下该type的出现次数,目标结构如下:
| zip code | person | property |
|---|---|---|
| 00000 | 1 | 0 |
| 00001 | 1 | 2 |
(注:示例数据对应实际统计值,原问题中目标表格的数值为占位示例)
已创建包含所有唯一zip code的df2,尝试以下两种方法均未得到正确结果:
- 全局求和错误:
df2 <- mutate(df2, person = sum(df1$type == "person"))
结果person列所有值为df1中person类型的全局总和,未按zip code分组统计。
- 循环逻辑错误:
for(i in nrow(df2)){ df2 <- mutate(df2, person = sum(df1[i,"type"] == "person")) }
结果person列全为0。
解决方案
错误原因分析
- 第一种方法:
sum(df1$type == "person")计算的是整个df1中type为person的总数,没有关联df2的zip code,因此所有行得到相同的全局统计值。 - 第二种方法:
for(i in nrow(df2))仅会循环一次(i等于df2的行数),且df1[i,"type"]取的是df1第i行的type,和df2第i行的zip code无匹配关系,导致统计结果错误。
推荐方法:使用tidyverse工具链(简洁高效)
通过分组计数+宽表转换,一步得到目标结果:
library(dplyr) library(tidyr) # 构造示例df1(可替换为实际数据) df1 <- tibble( state = c("NC", "NC", "NC", "NC"), `zip code` = c("00001", "00001", "00000", "00001"), type = c("person", "property", "person", "property") ) # 生成df2 df2 <- df1 %>% # 按zip code和type分组,统计每组数量 group_by(`zip code`, type) %>% summarise(count = n(), .groups = "drop") %>% # 将type列转换为列名,count作为对应值,缺失值填充0 pivot_wider(names_from = type, values_from = count, values_fill = 0)
循环实现方案(若需保留循环逻辑)
遍历每个唯一type,对df2的每个zip code匹配统计:
# 假设已创建包含唯一zip code的df2 unique_types <- unique(df1$type) for (t in unique_types) { # 对每个zip code,统计df1中对应zip且type匹配的数量 df2[[t]] <- sapply(df2$`zip code`, function(zip) { sum(df1$`zip code` == zip & df1$type == t) }) }
内容的提问来源于stack exchange,提问作者Nicholas Rios
相关产品推荐
相关产品推荐

