R-如何用Na.spline替换数据中的Na值



我正在尝试准备一些从欧洲群岛检索到的人口统计数据,以进行进一步处理,以及其他用相应的近似数据替换所有丢失的数据。

首先,我仅使用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

最新更新