0

有人要求我稍微分解一下我在这里提出的问题(R:应用累积和函数并用 NA 填充数据间隙进行绘图)并发布一个较小的样本。在这里,您可以在这里找到我的示例数据:https ://dl.dropboxusercontent.com/u/16277659/inputdata.csv

NAME;       ID;     SURVEY_YEAR;    REFERENCE_YEAR; VALUE
SAMPLE1;    253;    1883;           1883;           0
SAMPLE1;    253;    1884;           1883;           NA
SAMPLE1;    253;    1885;           1884;           12
SAMPLE1;    253;    1890;           1889;           17
SAMPLE2;    261;    1991;           1991;           0
SAMPLE2;    261;    1992;           1991;           -19
SAMPLE2;    261;    1994;           1992;           -58
SAMPLE2;    261;    1995;           1994;           -40

我想计算 VALUE 列的累积总和,并用 NA 值填充中间年份的数据空白(数据结构应该相同,因为我需要其他列进行进一步处理)。

填充数据间隙时,应像 SAMPLE1 一样填充 NA。在 CUMSUM 列中填写多个 NA 时,请注意 NA 后面的值的位置(例如,除了 VALUE 中的最后一个 NA(用于绘图原因)之外,应填写最后一个 CUMSUM 值。

REFERENCE_YEAR 和 SURVEY_YEAR 之间的期间大于一年的情况是一个例外,应将值写入列中,如 1992 年至 1994 年期间的 SAMPLE2 中的值。

这只是一个示例数据集,我的实际数据集由几列和大约 40000 行组成。最好是 BaseR 中的解决方案。每个 SAMPLE 的第一行中的 REFERENCE_YEAR 和 SURVEY_YEAR 相等是我用于为每个组编写零列的代码的结果。

NAME;       ID;     SURVEY_YEAR;    REFERENCE_YEAR; VALUE;  CUMSUM
SAMPLE1;    253;    1883;           1883;           0;      0
SAMPLE1;    253;    1884;           1883;           NA;     NA
SAMPLE1;    253;    1885;           1884;           12;     12
SAMPLE1;    253;    1886;           1885;           NA;     NA
SAMPLE1;    253;    1887;           1886;           NA;     NA
SAMPLE1;    253;    1888;           1887;           NA;     NA
SAMPLE1;    253;    1889;           1888;           NA;     12
SAMPLE1;    253;    1890;           1889;           17;     29
SAMPLE2;    261;    1991;           1991;           0;      0
SAMPLE2;    261;    1992;           1991;           -19;    -19
SAMPLE2;    261;    1993;           1992;           -58;    -77
SAMPLE2;    261;    1994;           1992;           -58;    -77
SAMPLE2;    261;    1995;           1994;           -40;    -117

-------------------------------------------------- ------------------------------------------


4

1 回答 1

3

如果dat是数据集,一种方法是:

SURVEY_YEAR通过在每个数据集的最小值和最大值之间展开来创建一个新数据集NAME

 dat1 <- setNames(stack(
             with(dat, tapply(SURVEY_YEAR, NAME, 
                FUN=function(x) seq(min(x), max(x)))))[2:1], c("NAME", "SURVEY_YEAR"))

将新数据集dat1与旧数据集合并dat

 datN <- merge(dat1, dat, all=TRUE)

将前一行中REFERENCE_YEAR的缺失值替换为SURVEY_YEAR

 datN$REFERENCE_YEAR[is.na(datN$REFERENCE_YEAR)] <- datN$SURVEY_YEAR[which(is.na(datN$REFERENCE_YEAR))-1]

使用na.locffromzoo填充 NA 的ID

 library(zoo)
 datN$ID <- na.locf(datN$ID)
 datN$CUMSUM <- NA

cumsum非 NAVALUE行和

 datN$CUMSUM[!is.na(datN$VALUE)] <-  unlist(with(datN, tapply(VALUE, NAME, FUN=function(x) cumsum(x[!is.na(x)]))))

查找在 SURVEY_YEAR 和 REFERENCE_YEAR >1 之间存在差异的行

 indx <- with(datN, SURVEY_YEAR-REFERENCE_YEAR)>1

用下一行值替换VALUE和中的那些行CUMSUM

 datN[,c("VALUE", "CUMSUM")] <- lapply(datN[,c("VALUE", "CUMSUM")], function(x) {x[which(indx)-1] <- x[indx]; x})

将一些NA值更改CUMSUM为以前的non-NA

datN$CUMSUM <- with(datN, ave(CUMSUM, NAME, FUN = function(x) {
x1 <- is.na(x)
rl <- rle(x1)
indx <- which(!(!(abs(x1 - 1) * (cumsum(x1) != 0) * sequence(rl$lengths)))) - 1
indx1 <- indx[indx - c(1, indx[-length(indx)]) > 1]
indxn <- unlist(lapply(indx1, function(y) {
    indx2 <- which(!is.na(x))
    tail(indx2[which(indx2 < y)], 1)
}))
x[indx1] <- x[indxn]
x
}))

datN
#      NAME SURVEY_YEAR  ID REFERENCE_YEAR VALUE CUMSUM
#1  SAMPLE1        1883 253           1883     0      0
#2  SAMPLE1        1884 253           1883    NA     NA
#3  SAMPLE1        1885 253           1884    12     12
#4  SAMPLE1        1886 253           1885    NA     NA
#5  SAMPLE1        1887 253           1886    NA     NA
#6  SAMPLE1        1888 253           1887    NA     NA
#7  SAMPLE1        1889 253           1888    NA     12
#8  SAMPLE1        1890 253           1889    17     29
#9  SAMPLE2        1991 261           1991     0      0
#10 SAMPLE2        1992 261           1991   -19    -19
#11 SAMPLE2        1993 261           1992   -58    -77
#12 SAMPLE2        1994 261           1992   -58    -77
#13 SAMPLE2        1995 261           1994   -40   -117
于 2014-08-13T04:53:25.840 回答