我使用R,试图利用其他列的条件值填充一列NA。数据帧有4列。下面介绍这4列。
“ Water_Level”:具有一些值,其中也包括NA。这是我要替换NA的列。将此列作为水箱中以升为单位的水量。
“坦克”:坦克的唯一标识。在此示例中,我有水箱1和水箱2。
“标志”:它具有一系列的0和1。当值为0时,打开水龙头,水位值减小0.05的常数。当flag为1时,将对水箱进行抽水,因此各个水箱中的水位逐渐增加到一系列1结束时的峰值。增加的速率各不相同,并且取决于“标志”列中1的长度或对应于1的序列末尾的计数器编号。
“ Counter”:一列,该列按顺序在flag列中计数0和1的数目。
我需要用其他列的条件填充“水位”列中的NA。
老实说,尽管清楚地了解了所需的结果,但我还是无法尝试任何事情。
df <- data.frame(
Water_level = c(67.92, rep(NA,9),67.96,10.5,rep(NA,8),20),
Flag = c(rep(0,5),rep(1,6),rep(0,5),rep(1,5)),
Tank= c(rep(1, 11), rep(2, 10)),
Counter = c(seq(1:5),seq(1:6), seq(1:5),seq(1:5))
)
df
Water_level Flag Tank Counter
1 67.92 0 1 1
2 NA 0 1 2
3 NA 0 1 3
4 NA 0 1 4
5 NA 0 1 5
6 NA 1 1 1
7 NA 1 1 2
8 NA 1 1 3
9 NA 1 1 4
10 NA 1 1 5
11 67.96 1 1 6
12 10.50 0 2 1
13 NA 0 2 2
14 NA 0 2 3
15 NA 0 2 4
16 NA 0 2 5
17 NA 1 2 1
18 NA 1 2 2
19 NA 1 2 3
20 NA 1 2 4
21 20.00 1 2 5
预期结果是按照我的简介中的条件描述,将水位填充到NA中。
例如,“水位”中的第2行应为67.92-0.05 = 67.87。这是因为分接头是打开的,即标志位于0。第3行为67.87-0.05 = 67.82,依此类推。
棘手的部分在第6行,即标志更改为1,即正在抽水。我们可以看到Tank 1的1系列在第11行结束。water_level的记录峰值为67.96。因此,从第6行到第10行的增长率现在可以在下面的公式中看到。
(67.96-第5行的值,遵循减少模式)/计数器的步数,在这种情况下为6
此计算将继续进行到Tank 2。
感谢您期待解决方案。
更新。
@manotheshark。这是一个好的开始。但这并不能很好地概括。当我将第12到16行包括在内时,它将产生错误的输出。也就是说,它不会从第11行下降0.05。
df <- data.frame(
Water_level = c(67.92, rep(NA,9),67.96, rep(NA,5),10.5,rep(NA,8),20),
Flag = c(rep(0,5),rep(1,6),rep(0,5),rep(0,5),rep(1,5)),
Tank= c(rep(1, 16), rep(2, 10)),
Counter = c(seq(1:5),seq(1:6),seq(1:5), seq(1:5),seq(1:5))
)
df
Water_level Flag Tank Counter
1 67.92 0 1 1
2 NA 0 1 2
3 NA 0 1 3
4 NA 0 1 4
5 NA 0 1 5
6 NA 1 1 1
7 NA 1 1 2
8 NA 1 1 3
9 NA 1 1 4
10 NA 1 1 5
11 67.96 1 1 6
12 NA 0 1 1
13 NA 0 1 2
14 NA 0 1 3
15 NA 0 1 4
16 NA 0 1 5
17 10.50 0 2 1
18 NA 0 2 2
19 NA 0 2 3
20 NA 0 2 4
21 NA 0 2 5
22 NA 1 2 1
23 NA 1 2 2
24 NA 1 2 3
25 NA 1 2 4
26 20.00 1 2 5
运行解决方案的输出如下所示。第12行应为67.96-0.05 = 67.91。
Water_level Flag Tank Counter
1 67.92000 0 1 1
2 67.87000 0 1 2
3 67.82000 0 1 3
4 67.77000 0 1 4
5 67.72000 0 1 5
6 67.30167 1 1 1
7 67.43333 1 1 2
8 67.56500 1 1 3
9 67.69667 1 1 4
10 67.82833 1 1 5
11 67.96000 1 1 6
12 67.37000 0 1 1
13 67.32000 0 1 2
14 67.27000 0 1 3
15 67.22000 0 1 4
16 67.17000 0 1 5
17 10.50000 0 2 1
18 10.45000 0 2 2
19 10.40000 0 2 3
20 10.35000 0 2 4
21 10.30000 0 2 5
22 12.24000 1 2 1
23 14.18000 1 2 2
24 16.12000 1 2 3
25 18.06000 1 2 4
26 20.00000 1 2 5
答案 0 :(得分:0)
未经测试是否可以在多个油箱循环中使用。将data.frame
转换为data.table
library(data.table)
setDT(df)
# calculate tank levels when dropping with Flag of 0
df[Flag == 0, Water_level := first(Water_level) - 0.05 * (.I - first(.I)), by = .(Flag, Tank)]
# use sequence to determine tank levels when filling from previous minimum to new max
df[Flag == 1, Water_level := seq(df[Flag == 0, last(Water_level), by = .(Flag, Tank)][,V1][.GRP], last(Water_level), length.out = .N + 1)[-1], by = .(Flag, Tank)]
> df
Water_level Flag Tank Counter
1: 67.92 0 1 1
2: 67.87 0 1 2
3: 67.82 0 1 3
4: 67.77 0 1 4
5: 67.72 0 1 5
6: 67.76 1 1 1
7: 67.80 1 1 2
8: 67.84 1 1 3
9: 67.88 1 1 4
10: 67.92 1 1 5
11: 67.96 1 1 6
12: 10.50 0 2 1
13: 10.45 0 2 2
14: 10.40 0 2 3
15: 10.35 0 2 4
16: 10.30 0 2 5
17: 12.24 1 2 1
18: 14.18 1 2 2
19: 16.12 1 2 3
20: 18.06 1 2 4
21: 20.00 1 2 5
Water_level Flag Tank Counter