在返回data.frame时,从列中减去非NA的第一列的值

时间:2016-11-17 11:04:04

标签: r

我有一个数据集,其中包含填写网络调查所花费的累积时间的变量(每个变量对应于调查的一页)。我需要变量显示的不是累积时间,而是仅显示在该页面上的时间。不幸的是,由于问卷中有过滤器,由于页面被过滤,一些变量有NA

这里有一些示例数据(第一个变量可以被视为基线而不包括任何NA):

   rts5032939 rts5032955 rts5032973 rts5032974 rts5032975 rts5032977 rts5032978 rts5032979 rts5033085 rts5033089
1          70         99         NA        104        111        119        132        147        175        196
3          33        144         NA        156        165         NA        199        259        297        357
15         18         57         NA         63         69         80         99        174        190        221
20       2107       2126         NA       2131       2139       2209       2220       2236         NA       2274
24       1088       1111         NA       1117       1124       1133       1152         NA       1208       1228
30         27         61         NA         70         83         90        182        230        298        336

这里有一个dput()供你使用:

test <- structure(list(rts5032939 = c(70, 33, 18, 2107, 1088, 27), rts5032955 = c(99, 
144, 57, 2126, 1111, 61), rts5032973 = c(NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_), rts5032974 = c(104, 
156, 63, 2131, 1117, 70), rts5032975 = c(111, 165, 69, 2139, 
1124, 83), rts5032977 = c(119, NA_real_, 80, 2209, 1133, 90), rts5032978 = c(132, 
199, 99, 2220, 1152, 182), rts5032979 = c(147, 259, 174, 2236, 
NA_real_, 230), rts5033085 = c(175, 297, 190, NA_real_, 1208, 298), rts5033089 = c(196, 
357, 221, 2274, 1228, 336)), .Names = c("rts5032939", "rts5032955", 
"rts5032973", "rts5032974", "rts5032975", "rts5032977", "rts5032978", 
"rts5032979", "rts5033085", "rts5033089"), row.names = c(1L, 
3L, 15L, 20L, 24L, 30L), class = "data.frame")

预期输出如下所示。请注意,变量不必替换,我对新生成的变量完全没问题。

   rts5032939 rts5032955 rts5032973 rts5032974 rts5032975 rts5032977 rts5032978 rts5032979 rts5033085 rts5033089
1          70         29         NA          5          7          8         13         15         28         21
3          33        111         NA         12          9         NA         34         60         38         60
15         18         39         NA          6          6         11         19         75         16         31
20       2107         19         NA          5          8         70         11         16         NA         38
24       1088         23         NA          6          7          9         19         NA         56         20
30         27         34         NA          9         13          7         92         48         68         38

在我注意到NA的问题之前,我使用了

for (i in 2:10) {
  df1[paste0("t_", i)] <- df1[i]-df1[i-1]
}

以减去的时间生成新变量。显然,当有时使用NA - 值时,这不起作用。

考虑到NA逐个发生,新方法必须遍历行行。说实话,我甚至不确定如何从这里开始。谁能指出我如何实现这一目标的方向?我对一般建议感到满意,因为我可以自己做具体的事情。

编辑:为了澄清,我需要输出只是该行之前的第一个非 - NA - 值的值和值之间的差异。 < / p>

1 个答案:

答案 0 :(得分:1)

希望这更好,但肯定会很慢!

abc <- function(x){
  zz = as.numeric(x)
  w <- 0
  for (i in 1:length(zz)){
    if (i==1){
      w[i] = 0
    } else {
      w[i] <- zz[i] - zz[max(which(!is.na(zz)[1:i-1]))]
    }  
  }
  return(w)
}

t(apply(test, 1, abc))

使用更快的方法获得解决方案(使用apply()) - 让我知道它在速度方面的表现

abc <- function(x){
  y = x[!is.na(x)] # get those non -NA values
  x[!is.na(x)] = c(y[1], diff(y)) # find the diff() of non NA ones and replace them to their original spot
  return(x)
}

t(apply(test, 1, abc))