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

如何为table()函数生成的列联表添加百分比列与总计列?

解决方案:给三维列联表添加百分比与总计列

一、直接用tidyverse管道实现(推荐)

无需拆分数据,通过tidy工具链直接生成包含频数、百分比和总计的结果表,结构与原列联表一致:

library(tidyverse)
library(magrittr)

result_df <- data1 %>%
  select(blockLabel, trial_resp.corr, participant) %>%
  # 生成基础频数列
  count(blockLabel, trial_resp.corr, participant, name = "Freq") %>%
  # 按被试+实验块分组计算百分比与总计
  group_by(participant, blockLabel) %>%
  mutate(
    pct = round(Freq / sum(Freq) * 100, 2),  # 计算块内百分比并保留两位小数
    total = sum(Freq)                        # 计算每个实验块的总试次数
  ) %>%
  # 转宽表,对齐原列联表结构
  pivot_wider(
    id_cols = c(participant, blockLabel, total),
    names_from = trial_resp.corr,
    values_from = c(Freq, pct),
    names_glue = "{trial_resp.corr}_{.value}"
  ) %>%
  ungroup()

print(result_df)

输出示例(截取部分):

# A tibble: 15 × 7
   participant blockLabel          total 0_Freq 1_Freq 0_pct 1_pct
   <fct>       <fct>               <int>  <int>  <int> <dbl> <dbl>
 1 pilot01     auditory_only          12      0     12   0    100  
 2 pilot01     bimodal_focus_aud…     72      1     71   1.39   98.6
 3 pilot01     bimodal_focus_vis…     72      3     69   4.17   95.8
 4 pilot01     divided               144     74     70  51.4    48.6
 5 pilot01     visual_only           12      0     12   0    100  

二、迭代实现方法

如果需要用迭代逻辑处理,以下提供三种常见方案:

1. 使用purrr::map(函数式迭代)

library(purrr)

# 按被试拆分数据
participant_list <- data1 %>%
  select(blockLabel, trial_resp.corr, participant) %>%
  group_split(participant)

# 定义单个被试数据的处理函数
process_single_participant <- function(df) {
  df %>%
    count(blockLabel, trial_resp.corr, name = "Freq") %>%
    group_by(blockLabel) %>%
    mutate(
      pct = round(Freq / sum(Freq) * 100, 2),
      total = sum(Freq)
    ) %>%
    pivot_wider(
      id_cols = c(blockLabel, total),
      names_from = trial_resp.corr,
      values_from = c(Freq, pct),
      names_glue = "{trial_resp.corr}_{.value}"
    ) %>%
    ungroup() %>%
    mutate(participant = unique(df$participant)) %>%
    select(participant, everything())
}

# 批量处理并合并结果
map_result <- map_dfr(participant_list, process_single_participant)
print(map_result)

2. 使用for循环迭代

# 获取所有被试ID
participant_ids <- unique(data1$participant)
# 初始化空结果框
loop_result <- tibble()

for (pid in participant_ids) {
  # 提取单个被试数据并处理
  sub_processed <- data1 %>%
    filter(participant == pid) %>%
    select(blockLabel, trial_resp.corr) %>%
    count(blockLabel, trial_resp.corr, name = "Freq") %>%
    group_by(blockLabel) %>%
    mutate(
      pct = round(Freq / sum(Freq) * 100, 2),
      total = sum(Freq)
    ) %>%
    pivot_wider(
      id_cols = c(blockLabel, total),
      names_from = trial_resp.corr,
      values_from = c(Freq, pct),
      names_glue = "{trial_resp.corr}_{.value}"
    ) %>%
    ungroup() %>%
    mutate(participant = pid) %>%
    select(participant, everything())
  
  # 合并到总结果
  loop_result <- bind_rows(loop_result, sub_processed)
}

print(loop_result)

3. 使用do.call结合lapply

# 用lapply批量处理每个被试
lapply_list <- lapply(participant_ids, function(pid) {
  data1 %>%
    filter(participant == pid) %>%
    select(blockLabel, trial_resp.corr) %>%
    count(blockLabel, trial_resp.corr, name = "Freq") %>%
    group_by(blockLabel) %>%
    mutate(
      pct = round(Freq / sum(Freq) * 100, 2),
      total = sum(Freq)
    ) %>%
    pivot_wider(
      id_cols = c(blockLabel, total),
      names_from = trial_resp.corr,
      values_from = c(Freq, pct),
      names_glue = "{trial_resp.corr}_{.value}"
    ) %>%
    ungroup() %>%
    mutate(participant = pid) %>%
    select(participant, everything())
})

# 用do.call合并结果
do.call_result <- do.call(bind_rows, lapply_list)
print(do.call_result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:50:24