You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中将apply输出的行唯一值计数转为指定格式数据框?

问题:按ID统计数值出现次数并重塑数据框

先复现原始数据:

library(dplyr)

dat <- data.frame(
    id = c(2341, 5849, 9085, 8570, 9918),
    week_1 = c("NULL", 0, 3, 5, 0),
    week_4 = c(0, 0, 2, 0, 3),
    week_8 = c(0, 1, 1, 4, 1)
)

df <- dat %>% 
    mutate_all(~replace(., lengths(.) == 0, NA)) %>%
    as.data.frame()

原始数据输出:

id week_1 week_4 week_8
1 2341   NULL      0      0
2 5849      0      0      1
3 9085      3      2      1
4 8570      5      0      4
5 9918      0      3      1

需求是按每个ID统计0-5的出现次数,生成r0到r5列,目标结果如下:

id r0 r1 r2 r3 r4 r5
1 2341  2  0  0  0  0  0
2 5849  2  1  0  0  0  0
3 9085  0  1  1  1  0  0
4 8570  1  0  0  0  1  1
5 9918  1  1  0  1  0  0

解决方案1:使用tidyverse工具链

这种方法逻辑直观,符合数据整理的常规流程:

library(tidyr)
library(dplyr)

# 1. 转成长格式,处理"NULL"为NA并过滤,将value转为数值型
long_df <- df %>%
    pivot_longer(cols = -id, names_to = "week", values_to = "value") %>%
    mutate(value = ifelse(value == "NULL", NA, as.numeric(value))) %>%
    filter(!is.na(value))

# 2. 按id和value计数,再转宽格式填充0,补充缺失列并排序
result_df <- long_df %>%
    count(id, value) %>%
    pivot_wider(
        id_cols = id,
        names_from = value,
        names_prefix = "r",
        values_from = n,
        values_fill = 0
    ) %>%
    mutate(across(paste0("r", 0:5), ~ifelse(is.na(.), 0, .))) %>%
    select(id, paste0("r", 0:5))

print(result_df)

输出结果:

# A tibble: 5 × 7
    id    r0    r1    r2    r3    r4    r5
  <dbl> <int> <int> <int> <int> <int> <int>
1  2341     2     0     0     0     0     0
2  5849     2     1     0     0     0     0
3  9085     0     1     1     1     0     0
4  8570     1     0     0     0     1     1
5  9918     1     1     0     1     0     0

解决方案2:使用base R实现

若偏好base R,可通过行循环结合因子统计完成:

# 定义需要统计的目标数值范围
target_vals <- 0:5

# 逐行处理数据
result_list <- lapply(1:nrow(df), function(i) {
    row_data <- df[i, -1]
    # 转换"NULL"为NA并过滤,转为数值型
    row_data <- as.numeric(ifelse(row_data == "NULL", NA, row_data))
    row_data <- row_data[!is.na(row_data)]
    
    # 用因子强制包含所有目标值,再统计次数
    tab <- table(factor(row_data, levels = target_vals))
    # 组合id和统计结果
    c(df$id[i], as.integer(tab))
})

# 转换为数据框并命名列
result_df <- as.data.frame(do.call(rbind, result_list))
colnames(result_df) <- c("id", paste0("r", target_vals))

print(result_df)

输出结果与tidyverse方法完全一致。


内容的提问来源于stack exchange,提问作者TimF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:55:04