将数据框列中的值替换为聚合/剪切的结果

时间:2017-03-16 20:02:49

标签: r

修改:修改模拟数据,以便价格意味着/中位数和邻居不会完美重叠。

我在数据框中有一个专栏,我们称之为Price。我只是在这里模拟数据:

a

和一组社区,我们称之为Hoods:

mydata = data.frame(index = rep(1:1000))
mydata$price[1:300]    = rnorm(250, mean = 10000, sd = 1000)
mydata$price[301:550]  = rnorm(250, mean = 25000, sd = 1000)
mydata$price[551:775]  = rnorm(250, mean = 75000, sd = 1000)
mydata$price[776:1000] = rnorm(250, mean = 100000, sd = 1000)

然后我按中位数价格汇总邻域,以创建一个中间值。我想以中位数价格区分邻里。

mydata$hoods = factor(c(rep('hood1',250),rep('hood2',250),rep('hood3',250),rep('hood4',250)))

然后我创建了邻居中位数的剪切版本(在我的实际数据中有24个邻域)。如下所示:

agg <- aggregate(mydata$price, by = list(hoods), FUN = median))

然后我想要替换每个&#39; hood1&#39;在具有聚合价格标签的原始数据中,依此类推所有社区。例如,前250个记录将是“低”。我知道我可以制作一些嵌套的if语句,或者强力硬编码。有没有人知道我可以一次性更有效地分配所有值的方法,因为我可以将它用于大于1000条记录的数据集。非常感谢您提供的任何帮助。

在最终输出中,分类的邻居(&#39;低&#39;,&#39;媒体&#39;&#39;高&#39;)不一定与刚刚相同根据原始数据对价格进行cut_aggregates <- cut(agg$x, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high')) ,因为某些街区会有“低”,“中等”和“高”的组合。使用这种策略。我想首先根据其聚合对每个邻域进行分类,然后重新编码邻域。

2 个答案:

答案 0 :(得分:1)

修改:方法1

mydata <- within(mydata, med <- ave(price, hoods, FUN = median) )
mydata$new_label <- cut(mydata$med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))

#   index     price hoods      med new_label
# 1     1 10084.756 hood1 10014.38       low
# 2     2 10226.460 hood1 10014.38       low
# 3     3 10432.556 hood1 10014.38       low
# 4     4 10558.065 hood1 10014.38       low
# 5     5 10059.755 hood1 10014.38       low
# 6     6  9885.359 hood1 10014.38       low

<强> Approach2:

由于agg$labshoodsmydata的每个级别都不是唯一的,因此最好通过将hoods的级别映射为一个循环来单独重新分配标签agg$labs

的值

如果agg$labs中的hoodsmydata的每个级别都有mydata$hoods <- factor( mydata$hoods, levels = agg$Group.1, labels = agg$labs )中的唯一标签,则只需通过agg$labs重新分配标签即可。但是,您在mydata$hoods <- as.character( mydata$hoods ) # convert factor to character agg$labs <- as.character(agg$labs) # convert factor to character for( i in seq_len( nrow( agg ) ) ) { # change labels for hoods in mydata mydata[ mydata$hoods %in% agg$Group.1[ i ], "hoods" ] <- agg$labs[i] } mydata$hoods <- factor( mydata$hoods ) # convert hoods back to factor unique(mydata$hoods) # output # [1] low medium high # Levels: high low medium 中有重复级别,因此您将按照以下步骤操作。

set.seed( 200 )
mydata = data.frame(index = rep(1:1000))
mydata$price[1:250]    = rnorm(250, mean = 10000, sd = 1000)
mydata$price[251:500]  = rnorm(250, mean = 25000, sd = 1000)
mydata$price[501:750]  = rnorm(250, mean = 75000, sd = 1000)
mydata$price[751:1000] = rnorm(250, mean = 100000, sd = 1000)
mydata$hoods = factor(c(rep('hood1',250),rep('hood2',250),rep('hood3',250),rep('hood4',250)))
agg <- with(mydata, aggregate( price, by = list(hoods), FUN = median) )
agg$labs <- cut(agg$x, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))

agg
#   Group.1         x   labs
# 1   hood1  10014.38    low
# 2   hood2  25021.96 medium
# 3   hood3  74963.40   high
# 4   hood4 100019.88   high

数据:

agg

如果您在set.seed()函数中选择其他种子,LINQ中的数据会有所不同。

答案 1 :(得分:1)

执行此操作的一种非常简单的方法,可能是最快的方法是使用data.table

library(data.table)

# convert mydata into a data.table
  setDT(mydata)

# calculate median price by hood 
  mydata[, med := median(price), by=hoods]

现在你可以:

# replace the original data of `hoods` with the new price labels
  mydata[, hoods := cut(med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))]

# or create new price labels in a new column
  mydata[, new_col := cut(med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))]

最后,如果您只需要每个引擎盖的摘要表:

  mydata[, (med = median(price)), by=.(hoods, new_col)]

 >    hoods my_cut        V1
 > 1: hood1    low  9916.564
 > 2: hood2    low 24696.864
 > 3: hood3   high 74749.481
 > 4: hood4   high 99852.744