在R中为创作者标记广告帖前3条帖子(求非循环解法)
解决方案
要实现将每个广告帖之前3条帖子标记为1的需求,我们可以利用向量化操作(无需循环),通过检查每条帖子之后的1-3条是否存在广告帖来生成目标变量。以下是两种高效实现方式:
方法一:使用dplyr(适合熟悉tidyverse的用户)
逻辑说明
- 按创作者分组,确保帖子按发布顺序(
posting_count)排列; - 用
lead()函数获取每条帖子之后第1、2、3条的ad值(没有后续帖子则填充0); - 若这三个值的和大于0,说明该帖子之后3条内存在广告帖,标记为1,否则为0。
代码实现
# 先修正数据类型(cbind生成的是矩阵,转成数据框并转换数值列) df <- as.data.frame(df) df$posting_count <- as.numeric(df$posting_count) df$ad <- as.numeric(df$ad) df$goal_variable <- as.numeric(df$goal_variable) library(dplyr) # 生成目标变量 df_result <- df %>% group_by(creator_id) %>% arrange(posting_count) %>% # 确保按发布顺序排序 mutate( lead1 = lead(ad, 1, default = 0), lead2 = lead(ad, 2, default = 0), lead3 = lead(ad, 3, default = 0), goal_variable_calc = as.integer(lead1 + lead2 + lead3 > 0) ) %>% ungroup() # 验证结果是否与预期一致 all(df_result$goal_variable == df_result$goal_variable_calc) # 输出:TRUE
方法二:使用data.table(适合大数据集,速度更快)
逻辑说明
与dplyr思路一致,利用shift()函数获取后续行的ad值,分组计算后生成目标变量,data.table的操作在大数据量下效率更高。
代码实现
# 修正数据类型 df <- as.data.frame(df) df$posting_count <- as.numeric(df$posting_count) df$ad <- as.numeric(df$ad) df$goal_variable <- as.numeric(df$goal_variable) library(data.table) setDT(df) # 生成目标变量 df_result <- df[order(creator_id, posting_count), `:=`(lead1 = shift(ad, type = "lead", n=1, fill=0), lead2 = shift(ad, type = "lead", n=2, fill=0), lead3 = shift(ad, type = "lead", n=3, fill=0), goal_variable_calc = as.integer(lead1 + lead2 + lead3 > 0)), by = creator_id] # 验证结果 all(df_result$goal_variable == df_result$goal_variable_calc) # 输出:TRUE
关键说明
- 两种方法均为无循环的向量化操作,避免了循环的低效率;
- 必须确保帖子按
posting_count排序,否则后续行的选取会出错; - 广告帖本身若在后续3条内存在其他广告帖,也会被标记为1(与你提供的示例结果一致)。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

