[英]Apply dplyr::starts_with() with lambda function
我有以下實施
library(dplyr)
library(tidyr)
dat = data.frame('A' = 1:3, 'C_1' = 1:3, 'C_2' = 1:3, 'M' = 1:3)
以下作品
dat %>% rowwise %>% mutate(Anew = list({function(x) c(x[1]^2, x[2] + 5, x[3] + 1)}(c(M, C_1, C_2)))) %>% ungroup %>% unnest_wider(Anew, names_sep = "")
但是,當我嘗試使用dplyr::starts_with()
查找列名時,下面不起作用
dat %>% rowwise %>% mutate(Anew = list({function(x) c(x[1]^2, x[2] + 5, x[3] + 1)}(c(M, starts_with('C_'))))) %>% ungroup %>% unnest_wider(Anew, names_sep = "")
關於如何在此上下文中正確應用starts_with()
的任何指示都將非常有幫助。
PS:這是我之前發布的Apply custom function that returns multiple values after dplyr::rowwise()的延續
starts_with
必須在選擇函數中使用,所以我們可以這樣寫。 across
也是一個選擇函數,因此我們可以交替使用across(M | starts_with('C_'))
代替select(...)
。 c_across
也是一個選擇函數,但它不保留名稱。
dat %>%
rowwise %>%
mutate(Anew = list({function(x) c(x[1]^2, x[2] + 5, x[3] + 1)}
(select(cur_data(), M, starts_with('C_'))))) %>%
ungroup %>%
unnest_wider(Anew, names_sep = "")
## # A tibble: 3 × 7
## A C_1 C_2 M AnewM AnewC_1 AnewC_2
## <int> <int> <int> <int> <dbl> <dbl> <dbl>
## 1 1 1 1 1 1 6 2
## 2 2 2 2 2 4 7 3
## 3 3 3 3 3 9 8 4
這里group_modify
也可以工作,並允許使用公式符號來指定匿名函數。 匿名函數中的索引已重新排序以對應於輸入中的順序。
dat %>%
group_by(A) %>%
group_modify(~ cbind(.x, Anew = c(.x[3]^2, .x[1] + 5, .x[2] + 1))) %>%
ungroup
## # A tibble: 3 × 7
## A C_1 C_2 M Anew.M Anew.C_1 Anew.C_2
## <int> <int> <int> <int> <dbl> <dbl> <dbl>
## 1 1 1 1 1 1 6 2
## 2 2 2 2 2 4 7 3
## 3 3 3 3 3 9 8 4
如果我們將c_across
包裝在starts_with
中並假設有第三列以C_
開頭,那么運行中的 lambda 函數將起作用
library(dplyr)
library(tidyr)
dat %>%
rowwise %>%
mutate(Anew = list((function(x) c(x[1]^2, x[2] + 5, x[3] +
1))(c_across(starts_with("C_"))))) %>%
unnest_wider(Anew, names_sep = "")
-輸出
# A tibble: 3 × 8
A C_1 C_2 C_3 M Anew1 Anew2 Anew3
<int> <int> <int> <int> <int> <dbl> <dbl> <dbl>
1 1 1 1 1 1 1 6 2
2 2 2 2 2 2 4 7 3
3 3 3 3 3 3 9 8 4
或者我們可以創建一個命名的函數rowwise
,而不是按行進行,並應用across
list
(會更有效率)
fns <- list(C_1 = function(x) x^2, C_2 = function(x) x + 5,
C_3 = function(x) x + 1)
dat %>%
mutate(across(starts_with("C_"),
~ fns[[cur_column()]](.x), .names = "Anew{seq_along(.fn)}"))
-輸出
A C_1 C_2 C_3 M Anew1 Anew2 Anew3
1 1 1 1 1 1 1 6 2
2 2 2 2 2 2 4 7 3
3 3 3 3 3 3 9 8 4
dat <- data.frame('A' = 1:3, 'C_1' = 1:3, 'C_2' = 1:3, C_3 = 1:3, 'M' = 1:3)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.