簡體   English   中英

R:如何使用來自利用其他多列的條件的值替換 dataframe 列中的 NA?

[英]R: How do I replace NAs in a dataframe column with values from conditions leveraging other multiple columns?

使用 R,我試圖用利用其他列條件的值填充列中的 NA。 數據框有 4 列。 4 列如下所述。

“Water_Level”:具有一些還包括 NA 的值。 這是我要替換 NA 的列。 將此列作為水箱中的水量(以升為單位)。

“坦克”:坦克的唯一標識符。 在這個示例中,我有坦克 1 和坦克 2。

“標志”:這有一系列 0 和 1。 當值為 0 時,水龍頭打開,Water_level 值減少 0.05 的常數。 當 flag 為 1 時,水箱正在被抽水,因此各個水箱中的水位逐漸上升到 1 序列結束時的峰值。 增加的速率是變化的,取決於標志列中 1 的長度或對應於 1 序列末尾的計數器編號。

“計數器”:按順序計算標志列中 0 和 1 的數量的列。

我需要用其他列的條件填充“Water_level”列中的 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

預期的結果是填充 Water_level 中的 NA,如我介紹中的條件所述。

例如,“Water_level”中的第 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 行時,它會產生錯誤的 output。 即它不會從第 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

運行您的解決方案的 output 如下所示。 第 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

未測試這是否適用於多個罐循環。 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM