我有时间序列/面板数据,包括加密的IMEI(每个手机独一无二,但不是每个用户独一无二)和手机品牌。 IMEI中不存在太多缺失值,但手机品牌中存在大量缺失值。由于独特的IMEI对应一个独特的手机,我们可以通过IMEI推断出缺失的品牌。
我的解决方案是使用我当前的数据构建IMEI到品牌表和merge(by=IMEI)
。
我只是好奇。还有其他办法吗?例如,在dplyr或data.table中,或者只是r-base函数。我的数据很大,有大约300万个观测值。
注意:用户可以拥有多个设备/ IMEI;品牌在开始时间,中间或结束时缺少一些时间。
# create sample data
user<-rep(letters[1:5],each=6)
time<-rep(1:6,5)
imei<-c(rep(100,6),rep(200,4),NA,201,rep(300,6),rep(400,3),401,404,404,rep(500,5),NA)
brand<-c(rep('Apple',3),NA,NA,'Apple',NA,rep('ZTE',4),NA,NA,NA,NA,rep('Samsung',3),NA,'Huawei',NA,'Nokia','HTC',NA,rep('Moto',6))
dt<-data.frame(time,user,imei,brand)
#data
time user imei brand
1 1 a 100 Apple
2 2 a 100 Apple
3 3 a 100 Apple
4 4 a 100 <NA>
5 5 a 100 <NA>
6 6 a 100 Apple
7 1 b 200 <NA>
8 2 b 200 ZTE
9 3 b 200 ZTE
10 4 b 200 ZTE
11 5 b NA ZTE
12 6 b 201 <NA>
13 1 c 300 <NA>
14 2 c 300 <NA>
15 3 c 300 <NA>
16 4 c 300 Samsung
17 5 c 300 Samsung
18 6 c 300 Samsung
19 1 d 400 <NA>
20 2 d 400 Huawei
21 3 d 400 <NA>
22 4 d 401 Nokia
23 5 d 404 HTC
24 6 d 404 <NA>
25 1 e 500 Moto
26 2 e 500 Moto
27 3 e 500 Moto
28 4 e 500 Moto
29 5 e 500 Moto
30 6 e NA Moto
答案 0 :(得分:2)
这是data.table
方法:
library(data.table)
setDT(dt)
setkey(dt, imei)
dt[dt, brand := unique(na.omit(brand)), imei]
# time user imei brand
# 1: 5 b NA ZTE
# 2: 6 e NA Moto
# 3: 1 a 100 Apple
# 4: 2 a 100 Apple
# 5: 3 a 100 Apple
# 6: 4 a 100 Apple
# 7: 5 a 100 Apple
# 8: 6 a 100 Apple
# 9: 1 b 200 ZTE
# 10: 2 b 200 ZTE
# 11: 3 b 200 ZTE
# 12: 4 b 200 ZTE
# 13: 6 b 201 NA
# 14: 1 c 300 Samsung
# 15: 2 c 300 Samsung
# 16: 3 c 300 Samsung
# 17: 4 c 300 Samsung
# 18: 5 c 300 Samsung
# 19: 6 c 300 Samsung
# 20: 1 d 400 Huawei
# 21: 2 d 400 Huawei
# 22: 3 d 400 Huawei
# 23: 4 d 401 Nokia
# 24: 5 d 404 HTC
# 25: 6 d 404 HTC
# 26: 1 e 500 Moto
# 27: 2 e 500 Moto
# 28: 3 e 500 Moto
# 29: 4 e 500 Moto
# 30: 5 e 500 Moto
# time user imei brand
这是dplyr
+ zoo::na.locf
方法:
library(dplyr)
library(zoo)
fillna <- function(x) na.locf(na.locf(x, na.rm = FALSE), fromLast = TRUE, na.rm = FALSE)
dt <- dt %>% group_by(imei) %>% mutate(brand = fillna(brand))
答案 1 :(得分:1)
这是一种经典的R方式:
dt$brand <- levels(dt$brand)[ave(as.numeric(dt$brand), dt$imei, FUN= function(x) mean(x, na.rm=TRUE))]
ave取一个数字参数,并按其他参数的级别对其执行FUN。然后它返回一个与原始数据长度相同的向量,每个imei具有相同的级别。
因为它需要一个数字参数,所以你不能将因子转储到ave中并获得最长的结果。你必须投入一个数字。那么,因子映射到与水平相对应的数字。因此,您可以找到平均水平(删除失踪后),然后将其用作原始水平的索引。