這似乎是一個相當簡單的任務,但學習的檔案后,我無法弄清楚ifelse(),dplyr::if_else()在SO和幾個類似的帖子有關應用ifelse()在資料幀的多個列。
我的目標:我有以下資料框,其中包含不同資料型別的列。在每一行上,如果列“有效”表示假,我想將前 3 列中的值重置為 NA。
問題:我使用dplyr::across()和ifelse()更改我想要的值,但日期列date和因子列team被強制為數字(如下面的reprex所示),這是不可取的。我知道這會dplyr::if_else()保留資料型別,但它也不適用于不同資料型別的列。
我知道tdf[tdf$valid == FALSE, !grepl("valid", names(tdf))] <- NA可以實作我的目標,但我更喜歡 tidyverse 方法,我可以在我的資料清理管道中使用它。提前謝謝了!
library(dplyr)
tdf <- tibble(
date = c(as.Date("2021-12-10"), as.Date("2021-12-11")),
team = factor(1:2, labels = c("T1", "T2")),
score = 3:4,
valid = c(TRUE, FALSE)
)
tdf
#> # A tibble: 2 x 4
#> date team score valid
#> <date> <fct> <int> <lgl>
#> 1 2021-12-10 T1 3 TRUE
#> 2 2021-12-11 T2 4 FALSE
tdf %>% mutate(across(-valid, ~ ifelse(valid, ., NA)))
#> # A tibble: 2 x 4
#> date team score valid
#> <dbl> <int> <int> <lgl>
#> 1 18971 1 3 TRUE
#> 2 NA NA NA FALSE
由reprex 包(v2.0.1)于 2021 年 12 月 10 日創建
uj5u.com熱心網友回復:
使用默認 ( TRUE) 選項,case_when其中NA根據型別回傳
library(dplyr)
tdf %>%
mutate(across(-valid, ~ case_when(valid ~ .)))
-輸出
# A tibble: 2 × 4
date team score valid
<date> <fct> <int> <lgl>
1 2021-12-10 T1 3 TRUE
2 NA <NA> NA FALSE
或者另一種選擇是 replace
tdf %>%
mutate(across(-valid, ~ replace(., !valid, NA)))
# A tibble: 2 × 4
date team score valid
<date> <fct> <int> <lgl>
1 2021-12-10 T1 3 TRUE
2 NA <NA> NA FALSE
根據 ?ifelse
結果的模式可能取決于test的值(參見示例),結果的類屬性(參見oldClass)取自test,可能不適用于yes和no中選擇的值。
有時最好使用諸如
(tmp <- 是; tmp[!test] <- 否[!test]; tmp)
,可能擴展到處理測驗中的缺失值。
uj5u.com熱心網友回復:
這是一個未解決的問題:
@akrun 給出了很好的解釋以及如何解決您的具體問題!
但如果你想保留ifelse:
在您的特定情況下,唯一有效的解決方案(帶有日期和因素)是由 Fabian Werner 在 2015 年使用自定義提供的safe.ifelse
如何防止 ifelse() 將 Date 物件轉換為數字物件
safe.ifelse <- function(cond, yes, no) {
class.y <- class(yes)
if (class.y == "factor") {
levels.y = levels(yes)
}
X <- ifelse(cond,yes,no)
if (class.y == "factor") {
X = as.factor(X)
levels(X) = levels.y
} else {
class(X) <- class.y
}
return(X)
}
tdf %>% mutate(across(-valid, ~ safe.ifelse(valid, ., NA)))
date team score valid
<date> <fct> <int> <lgl>
1 2021-12-10 T1 3 TRUE
2 NA NA NA FALSE
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/379744.html
