如何在R中将长格式数据的列响应转为独立二值宽列
R长格式转宽格式:生成水果响应二进制列
首先修正原数据的创建方式(cbind会生成字符矩阵,建议转为数据框避免类型问题):
id <- c(1,1,1,2,3,4,4,5,5,5) gender <- c("F","F","F","M","Unknown","F","F","M","M","M") fruit <- c("pear", "apple", "banana", "pear", "strawberry","banana", "banana", "pear", "strawberry", "banana") df <- data.frame(id, gender, fruit, stringsAsFactors = FALSE)
核心需求是:为每种水果生成二进制列,标记受访者是否出现过该水果(同一受访者重复的水果只算一次)。以下是三种实现方法:
方法一:使用tidyverse(代码易读,推荐)
library(tidyverse) # 1. 去重:保留每个受访者-水果的唯一组合 df_unique <- df %>% distinct(id, gender, fruit) # 2. 转换为宽格式 df_wide <- df_unique %>% pivot_wider( id_cols = c(id, gender), # 行标识:受访者ID和性别 names_from = fruit, # 列名来源:水果种类 values_fn = ~1, # 存在该水果则赋值1 values_fill = 0 # 不存在则填充0 )
方法二:使用data.table(适合大数据,效率更高)
library(data.table) setDT(df) # 转为data.table对象 # 去重:按ID和水果组合去重 df_unique <- unique(df, by = c("id", "fruit")) # 转换为宽格式 df_wide <- dcast( df_unique, id + gender ~ fruit, fun.aggregate = length, # 统计出现次数(去重后只会是1) fill = 0 # 缺失值填充0 )
方法三:基础R实现(无需额外安装包)
# 提取每个受访者的唯一性别信息 gender_df <- unique(df[, c("id", "gender")]) # 生成ID-水果交叉表,将重复次数转为1 fruit_table <- table(df$id, df$fruit) fruit_table[fruit_table > 1] <- 1 # 合并性别表与水果交叉表 df_wide <- merge( gender_df, as.data.frame.matrix(fruit_table), by.x = "id", by.y = "row.names" )
关键注意点
- 必须先对受访者ID-水果组合去重,否则转换后会得到重复次数,而非二进制标记
- 示例数据中每个ID对应唯一性别,若实际数据存在ID对应多种性别的情况,需提前清理或确认数据逻辑
内容的提问来源于stack exchange,提问作者user21027866
相关产品推荐
相关产品推荐

