我的数据包含日期,邮政编码和分数。 我想将数据离散化,以便同月的所有行和同一月份的平均值相同,邮政编码得到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)
我想在功能上这样做。 我知道如何在功能上使用一个条件(只是日期或只是拉链)而不是两个。我可以连接这两个字段来创建一个唯一的字段。这将是一个快速修复,但我想知道是否有一种方法可以使用apply函数或plyr简单有效地执行此操作。
答案 0 :(得分:1)
假设您的日期值已正确编码(例如)
score_df <- structure(list(date = structure(c(16072, 16073, 16074, 16075,
16076), class = "Date"), zip = c(12345L, 12345L, 12345L, 99885L,
99885L), score = c(10L, 20L, 2L, 15L, 12L)), .Names = c("date",
"zip", "score"), row.names = c(NA, -5L), class = "data.frame")
然后你可以做
with(score_df, ave(score, strftime(date, "%m"), zip,
FUN=function(x) ifelse(x>mean(x), 1, 0)))
# [1] 0 1 0 1 0
我们使用ave()
来计算所有月份/邮政编组的价值(我们使用strftime()
来获取该日期的月份。)
答案 1 :(得分:1)
我没有假设您有日期类变量(并且它们实际上是因素。)但是基本上沿着与MrFlick相同的路线进行检查:
> inp$above_avg <- with(inp, ave(score, zip, format(as.Date(date), "%m"), FUN=function(s) as.numeric(s > mean(s)) ) )
> inp
date zip score above_avg
1 2014-01-02 12345 10 0
2 2014-01-03 12345 20 1
3 2014-01-04 12345 2 0
4 2014-01-05 99885 15 1
5 2014-01-06 99885 12 0
答案 2 :(得分:1)
尝试使用data.table:
library(data.table)
ddt = data.table(score_df)
ddt[,above_avg:=ifelse(score>round(mean(score),0),1,0),]
ddt
date zip score above_avg
1: 2014-01-02 12345 10 0
2: 2014-01-03 12345 20 1
3: 2014-01-04 12345 2 0
4: 2014-01-05 99885 15 1
5: 2014-01-06 99885 12 0