我有日期、邮政编码和分数的数据。我想对数据进行离散化,以使同一月份的所有行和同一邮政编码高于同一月份的平均值,邮政编码为 1,所有其他行均为零。
示例(数据框称为 score_df):
date zip score
2014-01-02 12345 10
2014-01-03 12345 20
2014-01-04 12345 2
2014-01-05 99885 15
2014-01-06 99885 12
输出:
date zip score above_avg
2014-01-02 12345 10 0
2014-01-03 12345 20 1
2014-01-04 12345 3 0
2014-01-05 99885 15 1
2014-01-06 99885 12 0
到目前为止,我一直在使用低效的解决方案:
1.遍历所有月份并使用 ifelse 语句应用二进制条件
score_df$above_avg <- rep(0,length(score_df$score))
for (month in (1:12)) {
score_df$above_avg <- ifelse(as.numeric(substring(score_df$date,6,7)) == month,ifelse(score_df$score>quantile(score_df$score[as.numeric(substring(score_df$date,6,7)) == month],(0.5)),1,0),score_df$above_avg)
}
2.我还尝试使用聚合生成平均表,然后将平均列加入原始数据框,然后应用二进制条件
avg_by_month_zip <- aggregate(score~month+zip,data=score_df,FUN=mean)
score_df$mean <- sqldf("select * from score_df join avg_by_month_zip on avg_by_month_zip.zip = score_df.zip and avg_by_month_zip.month = score_df.month")
score_df$discrete <- ifelse(score_df$score>score_df$mean,1,0)
我想在功能上做到这一点。我知道如何在一个条件下(只是日期或只是 zip)在功能上做到这一点,但不是两个。我可以连接这两个字段以创建一个唯一字段。这将是一个快速解决方案,但我想知道是否有一种方法可以使用 apply 函数或 plyr 简单有效地完成此操作。