R - 用前面的值替换值,在选定的列中逐行开始和结束
R - Replace values with preceding value starting and ending in selected column by row
与类似,我想按行用前面的非零值替换开始列和结束列之间出现的任何零值。给定数据:
df <- structure(list(Mth1 = c(0L, 0L, 5L, 0L, 2L),
Mth2 = c(2L, 3L, 2L, 2L, 0L),
Mth3 = c(0L, 2L, 0L, 0L, 3L),
Mth4 = c(3L, 0L, 0L, 4L, 0L),
StartMth = c(2L, 2L, 1L, 2L, 1L),
EndMth = c(4L, 3L, 3L, 4L, 3L)),
.Names = c("Mth1", "Mth2", "Mth3", "Mth4", "StartMth", "EndMth"), class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))
> df
Mth1 Mth2 Mth3 Mth4 StartMth EndMth
1 0 2 0 3 2 4
2 0 3 2 0 2 3
3 5 2 0 0 1 3
4 0 2 0 4 2 4
5 2 0 3 0 1 3
我想使用 StartMth 和 EndMth 中的值来确定替换发生的位置。期望的输出是:
> df1
Mth1 Mth2 Mth3 Mth4
1 0 2 2 3
2 0 3 2 0
3 5 2 2 0
4 0 2 2 4
5 2 2 3 0
请注意,指定的 StartMth 和 EndMth 列中的值将始终为非零,并且 StartMth 之前的值和 EndMth 之后的值将始终为零。 StartMth 和 EndMth 列之间可能有零个、一个或多个零值需要替换。
编辑:实际的数据框有更多的月份和行,并且会随着时间的推移而增长,因此需要一个高效且通用的解决方案。 StartMth 和 EndMth 将始终是最后一列。
我怀疑解决方案涉及使用 apply
变体,可能对 NA 进行中间更改,然后应用 locf
以用前一个值填充现在缺失的值。
这似乎有效,但你能检查一下吗?
t(apply(X = df, MARGIN = 1, function(a)
replace(x = a[1:4],
list = (which(a[a[5]:a[6]] == 0) + a[5] - 1),
values = a[a[5]:a[6]][which(a[a[5]:a[6]] == 0)[1] - 1])))
# Mth1 Mth2 Mth3 Mth4
#1 0 2 2 3
#2 0 3 2 0
#3 5 2 2 0
#4 0 2 2 4
#5 2 2 3 0
与
df <- structure(list(Mth1 = c(0L, 0L, 5L, 0L, 2L),
Mth2 = c(2L, 3L, 2L, 2L, 0L),
Mth3 = c(0L, 2L, 0L, 0L, 3L),
Mth4 = c(3L, 0L, 0L, 4L, 0L),
StartMth = c(2L, 2L, 1L, 2L, 1L),
EndMth = c(4L, 3L, 3L, 4L, 3L)),
.Names = c("Mth1", "Mth2", "Mth3", "Mth4", "StartMth", "EndMth"), class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))
> df
Mth1 Mth2 Mth3 Mth4 StartMth EndMth
1 0 2 0 3 2 4
2 0 3 2 0 2 3
3 5 2 0 0 1 3
4 0 2 0 4 2 4
5 2 0 3 0 1 3
我想使用 StartMth 和 EndMth 中的值来确定替换发生的位置。期望的输出是:
> df1
Mth1 Mth2 Mth3 Mth4
1 0 2 2 3
2 0 3 2 0
3 5 2 2 0
4 0 2 2 4
5 2 2 3 0
请注意,指定的 StartMth 和 EndMth 列中的值将始终为非零,并且 StartMth 之前的值和 EndMth 之后的值将始终为零。 StartMth 和 EndMth 列之间可能有零个、一个或多个零值需要替换。
编辑:实际的数据框有更多的月份和行,并且会随着时间的推移而增长,因此需要一个高效且通用的解决方案。 StartMth 和 EndMth 将始终是最后一列。
我怀疑解决方案涉及使用 apply
变体,可能对 NA 进行中间更改,然后应用 locf
以用前一个值填充现在缺失的值。
这似乎有效,但你能检查一下吗?
t(apply(X = df, MARGIN = 1, function(a)
replace(x = a[1:4],
list = (which(a[a[5]:a[6]] == 0) + a[5] - 1),
values = a[a[5]:a[6]][which(a[a[5]:a[6]] == 0)[1] - 1])))
# Mth1 Mth2 Mth3 Mth4
#1 0 2 2 3
#2 0 3 2 0
#3 5 2 2 0
#4 0 2 2 4
#5 2 2 3 0