如何在R中基于Tone变量创建正面与负面计数变量?
解决方案
你的循环代码出问题的核心原因是列名不匹配:你代码里生成的列名是Tone1到Tone6,但数据集里的列名是Tone1.到Tone6.(末尾带点),导致每次循环都找不到对应列,求和结果全是NA。下面提供几种靠谱的解决方法:
方法一:修正循环代码
调整列名生成逻辑,同时处理NA值:
# 初始化计数列 gesis$count_pos <- 0 gesis$count_neg <- 0 for (i in 1:6) { # 匹配带点的Tone列名 current_col <- gesis[, paste0("Tone", i, ".")] # 累加正面计数(NA视为0) gesis$count_pos <- gesis$count_pos + ifelse(current_col == 1, 1, 0) # 累加负面计数(NA视为0) gesis$count_neg <- gesis$count_neg + ifelse(current_col == 2, 1, 0) } # 把可能出现的NA替换为0(比如所有Tone列都是NA的情况) gesis$count_pos[is.na(gesis$count_pos)] <- 0 gesis$count_neg[is.na(gesis$count_neg)] <- 0
方法二:用基础包的rowSums(推荐,简洁高效)
R的向量化操作比循环更简洁,直接批量统计:
# 筛选所有以Tone开头的列(自动匹配带点或不带点的列名) tone_cols <- grep("^Tone", colnames(gesis)) # 统计每条观测中正面(1)的次数,忽略NA gesis$count_pos <- rowSums(gesis[, tone_cols] == 1, na.rm = TRUE) # 统计每条观测中负面(2)的次数,忽略NA gesis$count_neg <- rowSums(gesis[, tone_cols] == 2, na.rm = TRUE)
方法三:用dplyr包(适合tidyverse用户)
如果你习惯用tidy语法,可以用across批量处理列:
library(dplyr) gesis <- gesis %>% mutate( # 统计正面次数 count_pos = rowSums(across(starts_with("Tone"), ~ .x == 1), na.rm = TRUE), # 统计负面次数 count_neg = rowSums(across(starts_with("Tone"), ~ .x == 2), na.rm = TRUE) )
测试示例数据
用你提供的df测试上述代码,会得到你期望的结果:
df <- data.frame( resp = c("a", "b", "c", "d"), Tone1 = c(1, 2, 3, 1), Tone2 = c(2, 2, 1, 1), Tone3 = c(1, NA, NA, 2), Tone4 = c(1, NA, NA, 2), Tone5 = c(2, NA, NA, 1), Tone6 = c(NA, NA, NA, 1)) tone_cols <- grep("^Tone", colnames(df)) df$count_pos <- rowSums(df[, tone_cols] == 1, na.rm = TRUE) df$count_neg <- rowSums(df[, tone_cols] == 2, na.rm = TRUE) print(df)
输出结果:
resp Tone1 Tone2 Tone3 Tone4 Tone5 Tone6 count_pos count_neg 1 a 1 2 1 1 2 NA 3 2 2 b 2 2 NA NA NA NA 0 2 3 c 3 1 NA NA NA NA 1 0 4 d 1 1 2 2 1 1 4 2
内容的提问来源于stack exchange,提问作者Sammy
相关产品推荐
相关产品推荐

