R语言:判断DataFrame的ID是否存在于另一DataFrame并计算流失率
问题解决:样本流失率计算与存在性标记
需求说明
现有两个不同时间点采样的DataFrame(df1、df2),存在样本流失和变量增减情况,需完成两项操作:
- 在df1中新增二进制列,标记每个
id是否存在于df2中 - 计算不同波次的样本流失率
样本数据
生成df1和df2的代码如下:
# df1 df1 <- structure(list(id = c("5ea1954758634f04542a50bf", "3fjkfgho55efy467grtu523r", "df79756gh5485trhfsdkig3d", "d6rg756ghuej4678dfdkig3d", "546dt547546hgdvc842a50bf"), var1 = 1:5, var2 = 3:7), row.names = c(-5L), class = "data.frame") # df2 df2 <- structure(list(id = c("73egdv4758634f04542a50bf", "3fjkfgho55efy467grtu523r", "tr54756gh5485trhfsdkig3d", "d6rg756ghuej4678dfdkig3d", "357dt547546hgdvc842a50bf"), var1 = 2:6, var4 = 3:7), row.names = c(-5L), class = "data.frame")
注:原代码中row.names设为-6L但仅包含5条数据,已修正为-5L避免报错。
错误尝试代码
用户尝试的代码未生效(未生成目标列):
df1 %>% mutate(in_df2 = c("no", "yes")[1 + (rowSums( outer( strsplit(id, "\\s+"), strsplit(df2$id, "\\s+"), Vectorize(function(x, y) all(x %in% y) | all(y %in% x)) ) ) > 0)])
问题分析:代码过度复杂(无需拆分无空格的id),且未将处理结果赋值回df1,导致修改未保存。
解决方案
1. 新增存在性标记列
直接使用%in%判断id是否存在,结合dplyr::mutate新增列:
library(dplyr) # 新增in_df2列,标记是否存在于df2 df1 <- df1 %>% mutate(in_df2 = ifelse(id %in% df2$id, "Yes", "No"))
执行后df1的输出结果:
id in_df2 var1 var2 1 5ea1954758634f04542a50bf No 1 3 2 3fjkfgho55efy467grtu523r Yes 2 4 3 df79756gh5485trhfsdkig3d No 3 5 4 d6rg756ghuej4678dfdkig3d Yes 4 6 5 546dt547546hgdvc842a50bf No 5 7
2. 计算样本流失率
流失率公式:(df1总样本数 - 留存样本数) / df1总样本数,代码实现:
# 计算样本流失率 total_samples <- nrow(df1) retained_samples <- sum(df1$in_df2 == "Yes") attrition_rate <- (total_samples - retained_samples) / total_samples # 输出结果,保留两位小数 cat(sprintf("样本流失率:%.2f%%", attrition_rate * 100))
执行后输出:样本流失率:60.00%
内容的提问来源于stack exchange,提问作者C_bath
相关产品推荐
相关产品推荐

