我有一個資料集,我需要將任何值為 0 但在過去 48 小時內具有非零值的值更改為特定字串。我猜我可能需要在執行此操作之前將除第一列之外的所有列從 dbl 轉換為 chr?
Time colA colB colC colD
<dttm> <dbl> <dbl> <dbl> <dbl>
1 2021-11-21 10:00:00 8 0 9 176
2 2021-11-11 11:00:00 21 0 22 416
3 2021-11-21 11:00:00 19 0 20 373
4 2021-11-11 12:00:00 40 13 28 566
5 2021-11-21 12:00:00 26 0 27 527
6 2021-11-11 13:00:00 50 20 32 651
7 2021-11-11 10:00:00 11 0 12 216
8 2021-11-21 13:00:00 30 0 31 617
9 2021-11-11 14:00:00 51 0 32 675
10 2021-11-21 14:00:00 31 0 32 644
很抱歉資料尚未按時間排序,正在努力解決這個問題。例如,這里的輸出,我會喜歡去:
Time colA colB colC colD
<dttm> <dbl> <dbl> <dbl> <dbl>
1 2021-11-21 10:00:00 8 0 9 176
2 2021-11-11 11:00:00 21 0 22 416
3 2021-11-21 11:00:00 19 0 20 373
4 2021-11-11 12:00:00 40 13 28 566
5 2021-11-21 12:00:00 26 0 27 527
6 2021-11-11 13:00:00 50 20 32 651
7 2021-11-11 10:00:00 11 0 12 216
8 2021-11-21 13:00:00 30 0 31 617
9 2021-11-11 14:00:00 51 STRING1 32 675
10 2021-11-21 14:00:00 31 0 32 644
由于 colB 在 2021-11-11 14:00:00 的值為 0,但在此之前的 48 小時內至少有 1 個先前值!= 0,因此它會更改為“STRING1”
抱歉,如果這令人困惑,我正在嘗試自動化我通常在 Excel 中手動執行的操作。提前致謝
uj5u.com熱心網友回復:
這是一個tidyverse解決方案。我將首先創建一些示例資料(請注意,我確實將其他列設定為字符):
data = tribble(
~ time, ~ colA, ~ colB,
"2021-11-21 12:00:00", 1, 0,
"2021-11-22 00:00:00", 0, 1,
"2021-11-24 12:00:00", 0, 0,
"2021-11-25 12:00:00", 1, 1,
"2021-11-26 12:00:00", 0, 0,
) %>%
mutate(
time = ymd_hms(time),
across(-time, as.character)
)
# A tibble: 5 x 3
time colA colB
<dttm> <chr> <chr>
1 2021-11-21 12:00:00 1 0
2 2021-11-22 00:00:00 0 1
3 2021-11-24 12:00:00 0 0
4 2021-11-25 12:00:00 1 1
5 2021-11-26 12:00:00 0 0
這個問題的挑戰在于,每次我們都需要知道要查找哪些其他行來確定每列的新值。要做到這一點,我將使用purrr:pmap()和.data可用的物件dplyr。我將首先演示如何“回顧”過去 48 小時內的行:
data %>%
mutate(
across(
.cols = -time,
function(col) {
pmap_chr(list(time), function(t) {
eligible = .data$time >= t - hours(48) & .data$time < t
paste(col[eligible], collapse = ",")
})
},
.names = "{.col}_previous"
)
)
輸出:
# A tibble: 5 x 5
time colA colB colA_previous colB_previous
<dttm> <chr> <chr> <chr> <chr>
1 2021-11-21 12:00:00 1 0 "" ""
2 2021-11-22 00:00:00 0 1 "1" "0"
3 2021-11-24 12:00:00 0 0 "" ""
4 2021-11-25 12:00:00 1 1 "0" "0"
5 2021-11-26 12:00:00 0 0 "0,1" "0,1"
如您所見,這看起來很有希望。我們已準備好以此為核心思想來開發解決方案。
data %>%
mutate(
across(
.cols = -time,
function(col) {
modify_ind = pmap_lgl(list(time), function(t) {
eligible = .data$time >= t - hours(48) & .data$time < t
any(col[eligible] != "0")
})
ifelse(modify_ind & col == "0", "STRING1", col)
}
)
)
輸出:
# A tibble: 5 x 3
time colA colB
<dttm> <chr> <chr>
1 2021-11-21 12:00:00 1 0
2 2021-11-22 00:00:00 STRING1 1
3 2021-11-24 12:00:00 0 0
4 2021-11-25 12:00:00 1 1
5 2021-11-26 12:00:00 STRING1 STRING1
一些注意事項:
- 在我的解決方案中,我創建了一個
modify_ind建立在前面所示想法的基礎上:訪問在過去 48 小時內按時間過濾的列,然后檢查是否有任何非零值。然后我修改列,只要它modify_ind是TRUE與列的值"0"。 - 如果您想創建新列而不是完全替換原始列,請添加一個
.names引數 toacross()如前所示。 - 如果您只想修改資料集中的幾列,而不是使用
across(.cols = -time),請使用類似across(.cols = c("colA", "colB")).
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/403829.html
標籤:
上一篇:熊貓根據另一列中的值求和相應的值
下一篇:加入資料框,保留列名
