我正在尝试准备从欧盟统计局检索的一些人口统计数据,以便进一步处理,其中包括用相应的近似数据替换任何缺失的数据。
首先我只使用data.frames,但后来我确信data.tables可能比常规data.frames有一些优势,所以我迁移到data.tables。
我这样做的一件事是在使用" na.spline"时得到了不同的结果。结合"申请"与" na.spline"作为data.table的一部分。
#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
分成&#34;行标题&#34; ...
(dt0a <- dt0[, 1, with=FALSE])
(cn0a <- colnames(dt0a))
......和人口数据......
(dt0b <- dt0[, 2:ncol(dt0), with=FALSE])
(cn0ba <- colnames(dt0b))
#2用&#34; na.spline&#34;替换 NA &安培; &#34;应用&#34;
(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在&#34; data.table&#34;
中替换 NA(dt2b <- dt0b[,lapply(.SD, na.spline, na.rm=FALSE)])
(dt2 <- cbind(dt0a, dt2b))
Et瞧...
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 计算的值是我感兴趣的值,仅通过方法#3生成。)
追求&#34; data.table&#34;路线(方法#3)是性能之一(正如在各个帖子中所指出的,当使用&#34;应用&#34;矩阵操作正在进行时,这比相应的方法花费相当长的时间促进&#34; data.table&#34; only。
对R来说很陌生我认为我已经做了一些非常根本错误的事情,唯一的问题是,我对这可能是什么并不了解。
任何帮助我指向正确方向的帮助都非常感谢!
-Sil68
答案 0 :(得分:1)
您正在apply
版本中执行逐行操作,并在data.table
版本中执行colwise操作。如果设置data.table
,则可以在by = 1:nrow(dt)
中执行逐行操作。
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
答案 1 :(得分:1)
使用矩阵。在matrix
上使用矩阵运算并不慢:
mat <- t(as.matrix(dt0[,-1,with=FALSE]))
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,with=FALSE]))
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,with=FALSE]))
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
&#34;运输&#34;结果显示@ shadow的解决方案的时间,它保留了OP的格式。由于apply
的工作原理,此处不需要na.spline
。