首次观察水平系数R时替换0

时间:2016-08-17 08:43:15

标签: r replace row

我有这个样本:

data <- structure(list(mmsi = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), 
    tr = c(1, 1, 1, 0, 2, 2, 0, 4, 4, 0, 5, 5)), .Names = c("mmsi", 
"tr"), row.names = c(NA, -12L), class = "data.frame")

对于每个tr,我想将tr列中的每个0替换为mmsi的先前值。

此功能适用于样本:

for ( i in levels(data$mmsi) ) {
data$test <- na.locf(with(data, { is.na(tr) <- tr == 0; tr }), fromLast = FALSE)}

但是当我使用更大的样本时,会出现一个问题:如果第一个值是0,那么我有一个错误(因为它找不到以前的值......)。

例如,如果我用

编辑小样本
data <- structure(list(mmsi = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), 
    tr = c(0, 1, 1, 0, 2, 2, 0, 4, 4, 0, 5, 5)), .Names = c("mmsi", 
"tr"), row.names = c(NA, -12L), class = "data.frame")

tr从前面的示例中的0开始,而不是1。如果我应用相同的函数for ( i in levels(data$mmsi) ) { data$test <- na.locf(with(data, { is.na(tr) <- tr == 0; tr }), fromLast = FALSE)},那么我当然有错误

Error in `$<-.data.frame`(`*tmp*`, "test", value = c(1, 1, 1, 2, 2, 2,  : 
  replacement has 11 rows, data has 12 

- &GT;该函数无法替换我更改的值(列tr中的第一个值)

我想我需要在我的函数中再添加一行,当它们作为tr中的第一个级别出现时,首先编辑0。新行应该用以下非零值替换0。然后剩下的功能就好了。

我正在寻找这个新专栏的输出是:

data$test
 [1] 1 1 1 1 2 2 2 4 4 4 5 5

知道如何获得这个吗?

1 个答案:

答案 0 :(得分:1)

我们可以使用其中一个按功能执行此操作。将“data.frame”转换为“data.table”(setDT(data)),按“mmsi”分组,在将“0”值替换为“{0}”之后应用na.locf(来自zoo) 'NA'并选择na.rm = FALSE,然后我们使用na.locf执行第二次fromLast = TRUE,将起始0(也称为NA)替换为下一个值。

library(data.table)
library(zoo)
setDT(data)[, test := na.locf(na.locf(replace(tr, tr==0, NA), 
                   na.rm=FALSE), fromLast=TRUE), by = mmsi]
data
#    mmsi tr test
# 1:    a  0    1
# 2:    a  1    1
# 3:    a  1    1
# 4:    a  0    1
# 5:    a  2    2
# 6:    a  2    2
# 7:    a  0    2
# 8:    b  4    4
# 9:    b  4    4
#10:    b  0    4
#11:    b  5    5
#12:    b  5    5

我们也可以在不使用na.locf

的情况下执行此操作
setDT(data)[, test := pmax(pmax(tr, shift((NA^!tr) * tr), na.rm = TRUE),1), mmsi]