基于其他列数值与条件计算新列consumers的R语言实现
R语言:计算数据框
consumers列的正确实现 原始数据框
df<- data.frame( id = c(1,1,1,1,2,2,2,3,3,4,4,4,5,5,5,5,5,6), age =c (41,43,20,8,33,30,6,45,90,60,7,3,50,50,7,1,83,45), activity = c(412,442,0,0,419,413,0,421,0,412,0,0,421,411,0,0,0,425), minute = c(10,15,0,0,20,15,0,25,0,20,0,0,25,20,0,0,0,30) )
计算需求
id为家庭标识,同个id下的记录属于同一家庭成员;activity列非零的成员为生产者,activity为0的是潜在消费者;- 活动类型规则:
412、442、413、419、411是面向15岁以下儿童的活动;421、425是面向15岁以上成人的活动; - 对应活动的
minute值需分配给目标消费者:若家庭中有多个对应消费者,每个消费者分配相同的时间总和。
预期输出
id age activity minute consumers 1 1 41 412 10 0 2 1 43 442 15 0 3 1 20 0 0 25 4 1 8 0 0 25 5 2 33 419 20 0 6 2 30 413 15 0 7 2 6 0 0 35 8 3 45 421 25 0 9 3 90 0 0 25 10 4 60 412 20 0 11 4 7 0 0 20 12 4 3 0 0 20 13 5 50 421 25 0 14 5 50 411 20 0 15 5 7 0 0 20 16 5 1 0 0 20 17 5 83 0 0 25 18 6 45 425 30 30
错误代码分析
你尝试的代码存在以下问题:
- 未区分活动对应的目标群体,直接对所有
minute求和,不符合“对应活动分配给目标消费者”的规则; - 仅判断了
age>15的潜在消费者,未覆盖age<=15的情况; - 未处理家庭中无潜在消费者时,生产者自身的分配逻辑(如
id=6的场景)。
df <- df %>% group_by(id) %>% mutate( consumers = ifelse(activity == 0 & age > 15, sum(minute), 0) )
正确实现方案
根据预期输出的逻辑,我们需要按家庭分组,分别计算儿童/成人活动的总时长,再根据潜在消费者的年龄、活动类型的单一性,以及是否存在潜在消费者来分配时长:
library(dplyr) df <- df %>% group_by(id) %>% mutate( # 计算面向儿童的活动总时长 child_activity_sum = sum(minute[activity %in% c(412, 442, 413, 419, 411)]), # 计算面向成人的活动总时长 adult_activity_sum = sum(minute[activity %in% c(421, 425)]), # 统计家庭中潜在消费者的数量 consumer_num = sum(activity == 0), # 判断家庭是否只有一种类型的活动 is_single_type = (child_activity_sum == 0) || (adult_activity_sum == 0), # 计算consumers列 consumers = case_when( # 生产者逻辑:无潜在消费者时,分配自身活动时长;否则为0 activity != 0 ~ ifelse(consumer_num == 0, minute, 0), # 潜在消费者逻辑:单一活动类型时分配全部对应时长,否则按年龄匹配对应活动时长 activity == 0 ~ ifelse(is_single_type, max(child_activity_sum, adult_activity_sum), ifelse(age < 15, child_activity_sum, adult_activity_sum)), # 默认值 TRUE ~ 0 ) ) %>% # 移除中间计算的辅助列 select(-child_activity_sum, -adult_activity_sum, -consumer_num, -is_single_type) %>% ungroup() # 输出结果 print(df)
运行上述代码后,将得到与预期完全一致的结果。
内容的提问来源于stack exchange,提问作者mehmo
相关产品推荐
相关产品推荐

