通过索引在 R 中填写大量 NA 数据?
Filling in a ton of NA data in R by indices?
我根据三件事索引了价格数据:
州、日期和 UPC(即产品代码)。
我有一堆 NA 价格。
我正在尝试通过以下方式填写 NA:对于给定的带有索引 (S,D,UPC) 的缺失价格,填写具有相同 S 和 UPC 的所有数据点的平均价格.即,取日期的平均值。
一定有一种非常简单的方法可以做到这一点,因为这非常简单。我一直在使用 for 循环,但我现在意识到这是非常低效的,我想使用一个函数,例如 plyr 或 dplyr 中的一个函数,它将以尽可能少的步骤完成所有操作。
upc=c(1153801013,1153801013,1153801013,1153801013,1153801013,1153801013,2105900750,2105900750,2105900750,2105900750,2105900750,2173300001,2173300001,2173300001,2173300001)
date=c(200601,200602,200603,200604,200601,200602,200601,200602,200603,200601,200602,200603,200604,200605,200606)
price=c(26,28,NA,NA,23,24,85,84,NA,81,78,24,19,98,NA)
state=c(1,1,1,1,2,2,1,1,2,2,2,1,1,1,1)
# This is what I have:
data <- data.frame(upc,date,state,price)
# This is what I want:
price=c(26,28,27,27,23,24,85,84,79.5,81,78,24,19,98,47)
data2 <- data.frame(upc,date,state,price)
有什么建议吗?谢谢
对多个分组变量使用ave
,然后将NA
值替换为:
with(data,
ave(price, list(upc,state), FUN=function(x) replace(x,is.na(x),mean(x,na.rm=TRUE) ) )
)
# [1] 26.0 28.0 27.0 27.0 23.0 24.0 85.0 84.0 79.5 81.0 78.0 24.0 19.0 98.0 47.0
你可以通过upc和state构造均值矩阵:
meanmtx <- tapply(dat$price, dat[c('upc','state')], mean, na.rm=TRUE)
该矩阵具有可与 upc
和 state
中的值匹配的字符索引。所以然后使用 2 列字符索引将它们放在空 "slots":
dat$price[is.na(dat$price)] <-
meanmtx[ cbind( as.character(dat[ is.na(dat$price), 'upc']),
as.character(dat[ is.na(dat$price),'state']) ) ]
> dat
upc date state price
1 1153801013 200601 1 26.0
2 1153801013 200602 1 28.0
3 1153801013 200603 1 27.0
4 1153801013 200604 1 27.0
5 1153801013 200601 2 23.0
6 1153801013 200602 2 24.0
7 2105900750 200601 1 85.0
8 2105900750 200602 1 84.0
9 2105900750 200603 2 79.5
10 2105900750 200601 2 81.0
11 2105900750 200602 2 78.0
12 2173300001 200603 1 24.0
13 2173300001 200604 1 19.0
14 2173300001 200605 1 98.0
15 2173300001 200606 1 47.0
这是另一个使用 na.aggregate
(来自 zoo
)和 data.table
的紧凑选项。默认情况下,na.aggregate
将 NA
值替换为感兴趣列的 mean
。它还有一个 FUN
参数,以防我们想用 median
、min
或 max
或任何我们想要的替换 NA。分组操作可以通过 dplyr/data.table/base R 方法完成。使用 data.table
,我们将 'data.frame' 转换为 'data.table' (setDT(data)
),按 'upc'、'state' 分组,我们分配 (:=
) 'price' 作为 'price' 的 na.aggregate
。
library(data.table)
library(zoo)
setDT(data)[, price:= na.aggregate(price) , .(upc, state)]
我根据三件事索引了价格数据:
州、日期和 UPC(即产品代码)。
我有一堆 NA 价格。
我正在尝试通过以下方式填写 NA:对于给定的带有索引 (S,D,UPC) 的缺失价格,填写具有相同 S 和 UPC 的所有数据点的平均价格.即,取日期的平均值。
一定有一种非常简单的方法可以做到这一点,因为这非常简单。我一直在使用 for 循环,但我现在意识到这是非常低效的,我想使用一个函数,例如 plyr 或 dplyr 中的一个函数,它将以尽可能少的步骤完成所有操作。
upc=c(1153801013,1153801013,1153801013,1153801013,1153801013,1153801013,2105900750,2105900750,2105900750,2105900750,2105900750,2173300001,2173300001,2173300001,2173300001)
date=c(200601,200602,200603,200604,200601,200602,200601,200602,200603,200601,200602,200603,200604,200605,200606)
price=c(26,28,NA,NA,23,24,85,84,NA,81,78,24,19,98,NA)
state=c(1,1,1,1,2,2,1,1,2,2,2,1,1,1,1)
# This is what I have:
data <- data.frame(upc,date,state,price)
# This is what I want:
price=c(26,28,27,27,23,24,85,84,79.5,81,78,24,19,98,47)
data2 <- data.frame(upc,date,state,price)
有什么建议吗?谢谢
对多个分组变量使用ave
,然后将NA
值替换为:
with(data,
ave(price, list(upc,state), FUN=function(x) replace(x,is.na(x),mean(x,na.rm=TRUE) ) )
)
# [1] 26.0 28.0 27.0 27.0 23.0 24.0 85.0 84.0 79.5 81.0 78.0 24.0 19.0 98.0 47.0
你可以通过upc和state构造均值矩阵:
meanmtx <- tapply(dat$price, dat[c('upc','state')], mean, na.rm=TRUE)
该矩阵具有可与 upc
和 state
中的值匹配的字符索引。所以然后使用 2 列字符索引将它们放在空 "slots":
dat$price[is.na(dat$price)] <-
meanmtx[ cbind( as.character(dat[ is.na(dat$price), 'upc']),
as.character(dat[ is.na(dat$price),'state']) ) ]
> dat
upc date state price
1 1153801013 200601 1 26.0
2 1153801013 200602 1 28.0
3 1153801013 200603 1 27.0
4 1153801013 200604 1 27.0
5 1153801013 200601 2 23.0
6 1153801013 200602 2 24.0
7 2105900750 200601 1 85.0
8 2105900750 200602 1 84.0
9 2105900750 200603 2 79.5
10 2105900750 200601 2 81.0
11 2105900750 200602 2 78.0
12 2173300001 200603 1 24.0
13 2173300001 200604 1 19.0
14 2173300001 200605 1 98.0
15 2173300001 200606 1 47.0
这是另一个使用 na.aggregate
(来自 zoo
)和 data.table
的紧凑选项。默认情况下,na.aggregate
将 NA
值替换为感兴趣列的 mean
。它还有一个 FUN
参数,以防我们想用 median
、min
或 max
或任何我们想要的替换 NA。分组操作可以通过 dplyr/data.table/base R 方法完成。使用 data.table
,我们将 'data.frame' 转换为 'data.table' (setDT(data)
),按 'upc'、'state' 分组,我们分配 (:=
) 'price' 作为 'price' 的 na.aggregate
。
library(data.table)
library(zoo)
setDT(data)[, price:= na.aggregate(price) , .(upc, state)]