[英]How to apply this function columnwise with across() in tidyverse?
我需要在 tidyverse 中使用 function 基於現有列創建新列。 我計划使用across()
,因為它允許動態重命名新變量,這在我的情況下變得越來越重要,並且可以節省大量時間,特別是如果您的數據中有很多變量需要修改。 下面的 function 無法按預期按列應用,它的行為很奇怪,通過更改P
參數的值,我每次都得到意想不到的 output,尤其是當我將一些值設置為 1 時,就好像應用了 ZC1C41252074 元素一樣但不是按列。
我想知道如何以更有效的方式編寫這段代碼來實現上述目標,我的意思是高效,更短,更快,更整潔。
代表
set.seed (123)
df <- tibble(id = 1:10,
rosa = runif(10, min = 20.8, max = 36.5),
lila = runif(10, min = 17, max = 37),
blaue = runif(10, min = 23.3, max = 32.7))
df[c (2, 5, 8), c (2:4)] <- NA
代碼
myfun <- function(x, P = 2, na.rm = FALSE){
P ^ (min (x, na.rm = na.rm) - x)
}
P <- c(2, 1.5, 1.1) # fiddle with numbers here and see the output each time changes
names <- c ("rosa", "lila", "blaue")
df %>%
select(!!names) %>%
mutate(across(.cols = !!names,
.fns = ~myfun(.x, P, na.rm = TRUE),
.names = "{.col}_P"))
Output
+ # A tibble: 10 × 6
rosa lila blaue rosa_P lila_P blaue_P
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 25.3 36.1 31.7 0.0718 0.0000526 0.00793
2 NA NA NA NA NA NA
3 27.2 30.6 29.3 0.581 0.439 0.643
4 34.7 28.5 32.6 0.000110 0.0108 0.00401
5 NA NA NA NA NA NA
6 21.5 35.0 30.0 1 0.288 0.605
7 29.1 21.9 28.4 0.00524 1 0.0753
8 NA NA NA NA NA NA
9 29.5 23.6 26.0 0.469 0.856 0.881
10 28.0 36.1 24.7 0.0114 0.0000543 1
Warning messages:
1: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length
2: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length
3: Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length
預計 Output
df %>%
select(!!names) %>%
mutate(rosa_P = 2^(min (rosa, na.rm = TRUE) - rosa)) %>%
mutate(lila_P = 1.5^(min (lila, na.rm = TRUE) - lila)) %>%
mutate(blaue_P = 1.1^(min (blaue, na.rm = TRUE) - blaue))
+ # A tibble: 10 × 6
rosa lila blaue rosa_P lila_P blaue_P
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 25.3 36.1 31.7 0.0718 0.00314 0.514
2 NA NA NA NA NA NA
3 27.2 30.6 29.3 0.0192 0.0302 0.643
4 34.7 28.5 32.6 0.000110 0.0708 0.468
5 NA NA NA NA NA NA
6 21.5 35.0 30.0 1 0.00498 0.605
7 29.1 21.9 28.4 0.00524 1 0.701
8 NA NA NA NA NA NA
9 29.5 23.6 26.0 0.00407 0.515 0.881
10 28.0 36.1 24.7 0.0114 0.00320 1
您的問題是P
向量,因為它不會理解哪個數字屬於哪個呼叫,但會將across
三個數字都傳遞給myfun
。 相反,您可以命名它並使用cur_column()
。
使用all_of
/ any_of
而不是 , 並為名稱向量使用另一個
names
而不是names
,因為它也是基礎 function。 這可能會導致混亂。
library(dplyr)
P <- c(rosa = 2, lila = 1.5, blaue = 1.1)
colournames <- names(P) #c("rosa", "lila", "blaue")
df |>
#select(all_of(colournames)) |>
mutate(across(all_of(colournames),
~ P[cur_column()] ^ (min(., na.rm = TRUE) - .), # ~ my_fun(., P[cur_column()], na.rm = TRUE)
.names = "{.col}_P"))
Output:
# A tibble: 10 × 6
rosa lila blaue rosa_P lila_P blaue_P
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 25.3 36.1 31.7 0.0718 0.00314 0.514
2 NA NA NA NA NA NA
3 27.2 30.6 29.3 0.0192 0.0302 0.643
4 34.7 28.5 32.6 0.000110 0.0708 0.468
5 NA NA NA NA NA NA
6 21.5 35.0 30.0 1 0.00498 0.605
7 29.1 21.9 28.4 0.00524 1 0.701
8 NA NA NA NA NA NA
9 29.5 23.6 26.0 0.00407 0.515 0.881
10 28.0 36.1 24.7 0.0114 0.00320 1
更新,隨着 OP 示例的更改而更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.