如何使用na.spline

时间:2015-05-06 11:44:59

标签: r data.table apply spline

我正在尝试准备从欧盟统计局检索的一些人口统计数据,以便进一步处理,其中包括用相应的近似数据替换任何缺失的数据。

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

2 个答案:

答案 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