我正在尝试准备一些从欧洲群岛检索到的人口统计数据,以进行进一步处理,以及其他用相应的近似数据替换所有丢失的数据。
首先,我仅使用data.frames,但后来我确信数据。Tables可能比常规数据提供了一些优势。
我在这样做时观察到的一件事是,当使用" na.spline"与" apply"与" na.spline"结合使用时,获得了不同的结果。
。#1源数据
(dt0 <- data.table(
"age,sex,geo\time" = c("TOTAL,F,AD", "TOTAL,F,AL", "TOTAL,F,AM", "TOTAL,F,AT", "TOTAL,F,AZ"),
"2014" = c(NA, NA, NA, 4351253, NA),
"2013" = c(37408, NA, NA, 4328238, 4707690),
"2012" = c(38252, NA, 1684000, 4309977, 4651601),
"2011" = c(38252, 1409931, 1679066, 4296293, 4594023),
"2010" = c(40296, NA, 1673656, 4285442, 4542083)
))
生成
age,sex,geo\time 2014 2013 2012 2011 2010
1: TOTAL,F,AD NA 37408 38252 38252 40296
2: TOTAL,F,AL NA NA NA 1409931 NA
3: TOTAL,F,AM NA NA 1684000 1679066 1673656
4: TOTAL,F,AT 4351253 4328238 4309977 4296293 4285442
5: TOTAL,F,AZ NA 4707690 4651601 4594023 4542083
拆分为"行标题" ...
(dt0a <- dt0[, 1, with=FALSE])
(cn0a <- colnames(dt0a))
...和人口数据...
(dt0b <- dt0[, 2:ncol(dt0), with=FALSE])
(cn0ba <- colnames(dt0b))
#2替换 na s由" na.spline"&amp;"应用"
(dt1b <- data.table(t(apply(dt0b, 1, na.spline, na.rm=FALSE))))
(setnames(dt1b, cn0b))
(dt1 <- cbind(dt0a, dt1b))
导致...
age,sex,geo\time 2014 2013 2012 2011 2010
1: TOTAL,F,AD 32832 37408 38252 38252 40296
2: TOTAL,F,AL 1409931 1409931 1409931 1409931 1409931
3: TOTAL,F,AM 1692440 1688458 1684000 1679066 1673656
4: TOTAL,F,AT 4351253 4328238 4309977 4296293 4285442
5: TOTAL,F,AZ 4755163 4707690 4651601 4594023 4542083
#3替换 na 在" data.table"
(dt2b <- dt0b[,lapply(.SD, na.spline, na.rm=FALSE)])
(dt2 <- cbind(dt0a, dt2b))
et voila ...
age,sex,geo\time 2014 2013 2012 2011 2010
1: TOTAL,F,AD 4351253 37408 38252.0 38252 40296.0
2: TOTAL,F,AL 4351253 1993097 -611513.8 1409931 -629363.2
3: TOTAL,F,AM 4351253 3423374 1684000.0 1679066 1673656.0
4: TOTAL,F,AT 4351253 4328238 4309977.0 4296293 4285442.0
5: TOTAL,F,AZ 4351253 4707690 4651601.0 4594023 4542083.0
#4比较结果
(identical(dt1, dt2))
考虑到上述并不令人惊讶...
[1] FALSE
(用方法2计算为 na na 的值是我感兴趣的,仅通过方法#3生成)。
追求" data.table"路线的原因(方法#3)是性能之一(正如在使用"应用"应用"矩阵操作的各种帖子中指出的那样,正在执行比相应的方法促进"数据"仅比相应的方法更长)。
我认为我已经做了很大的错误,唯一的事情是,我没有最淡淡的想法。
任何帮助我指向正确方向的帮助!
-sil68
使用矩阵。在matrix
上使用矩阵操作并不慢:
mat <- t(as.matrix(dt0[,-1]))
colnames(mat) <- dt0[[1]]
mat[] <- na.spline(mat,na.rm=FALSE)
给出
TOTAL,F,AD TOTAL,F,AL TOTAL,F,AM TOTAL,F,AT TOTAL,F,AZ
2014 32832 1409931 1692440 4351253 4755163
2013 37408 1409931 1688458 4328238 4707690
2012 38252 1409931 1684000 4309977 4651601
2011 38252 1409931 1679066 4296293 4594023
2010 40296 1409931 1673656 4285442 4542083
使用data.table。如果您想使用data.table
,请
mat <- t(as.matrix(dt0[,-1]))
colnames(mat) <- dt0[[1]]
DT <- data.table(mat,keep.rownames=TRUE)
DT[,(vn):=lapply(.SD,na.spline,na.rm=FALSE),.SDcols=vn]
通过参考更新DT
,给出
rn TOTAL,F,AD TOTAL,F,AL TOTAL,F,AM TOTAL,F,AT TOTAL,F,AZ
1: 2014 32832 1409931 1692440 4351253 4755163
2: 2013 37408 1409931 1688458 4328238 4707690
3: 2012 38252 1409931 1684000 4309977 4651601
4: 2011 38252 1409931 1679066 4296293 4594023
5: 2010 40296 1409931 1673656 4285442 4542083
基准测试:
mat <- t(as.matrix(dt0[,-1]))
colnames(mat) <- dt0[[1]]
DT <- data.table(mat,keep.rownames=TRUE)
vn <- names(DT)[-1]
tvn <- names(dt0)[-1]
require(microbenchmark)
microbenchmark(
transp = dt0[,as.list(na.spline(unlist(.SD), na.rm=FALSE)),by=1:nrow(dt0),.SDcols=tvn],
lapply = DT[,lapply(.SD,na.spline,na.rm=FALSE),.SDcols=vn],
apply = apply(mat,2,na.spline,na.rm=FALSE),
fun = na.spline(mat,na.rm=FALSE),
times=10)
结果:
Unit: milliseconds
expr min lq mean median uq max neval
transp 4.666934 4.734891 4.850268 4.787690 4.897202 5.259957 10
lapply 3.923823 4.010356 4.327646 4.039445 4.049957 6.976446 10
apply 2.505556 2.525601 2.578890 2.585978 2.592090 2.758801 10
fun 1.945290 1.994178 2.063063 2.068490 2.085112 2.272846 10
" transp"结果显示了 @Shadow解决方案的时机,该解决方案保留了OP的格式。apply
在这里不需要na.spline
的工作原理。
您在apply
版本中进行行操作,并在data.table
版本中进行Colwise操作。如果设置by = 1:nrow(dt)
,则可以在data.table
中进行行操作。
dt2b <- dt0b[, as.list(na.spline(unlist(.SD), na.rm=FALSE)), by = 1:nrow(dt0b)]
您也可以使用.SDcols
,因此您无需拆分数据。如果age,sex,geo\time
是唯一的,则以下将有效:
dt0[, as.list(na.spline(unlist(.SD), na.rm=FALSE)), by = `age,sex,geo\time`, .SDcols = -"age,sex,geo\time"]
## age,sex,geo\time V1 V2 V3 V4 V5
## 1: TOTAL,F,AD 32832 37408 38252 38252 40296
## 2: TOTAL,F,AL 1409931 1409931 1409931 1409931 1409931
## 3: TOTAL,F,AM 1692440 1688458 1684000 1679066 1673656
## 4: TOTAL,F,AT 4351253 4328238 4309977 4296293 4285442
## 5: TOTAL,F,AZ 4755163 4707690 4651601 4594023 4542083