我在這里尋找解決方案:將資料框中的列乘以向量,在這里:將資料框乘以向量的正確方法是什么?,但它并沒有真正起作用。
我想要做的是一種或多或少干凈整潔的方式,我將列乘以向量,然后將這些作為新列添加到現有資料框中。以第一個鏈接中的資料示例為例:
c1 <- c(1,2,3)
c2 <- c(4,5,6)
c3 <- c(7,8,9)
d1 <- data.frame(c1,c2,c3)
c1 c2 c3
1 1 4 7
2 2 5 8
3 3 6 9
v1 <- c(1,2,3)
我想要的結果是:
c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
我試過了:
library(tidyverse)
d1 |>
mutate(pro = sweep(across(everything()), 2, v1, "*"))
但這里的問題是新列實際上是我的資料框中的一個資料框。我正在努力將這個資料幀中的資料框變成常規列。我假設,我可能首先在這個內部資料幀上設定名稱,然后再取消嵌套,但想知道是否有更直接的方法,通過回圈遍歷每一列across并用 的第一個/第二個/第三個元素提供它v1?
(我知道我也可以先用三個新的相乘列創建一個獨立的資料框,給它們一個唯一的名稱,然后bind_cols在 d1 和帶有產品的 df 上。)
uj5u.com熱心網友回復:
這可能很荒謬,但你可以使用
library(dplyr)
d1 %>%
mutate(across(everything(),
~.x * v1[which(names(d1) == cur_column())],
.names = "pro_{.col}"))
回傳
c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
uj5u.com熱心網友回復:
只是為了有趣的部分,在看到您的一些解決方案后,我嘗試并犯了更多錯誤。自從我開始忍受使用不允許傳遞“。”的基本 R 原生管道的痛苦以來。默默地爭論作為第一個論點,我不得不更多地擺弄它:
library(tidyverse)
d1 |>
(\(x)(bind_cols(x, x |>
map2_dfc(v1, `*`) |>
rename_with(.cols = everything(),
.fn = ~paste0("pro_", .)))))()
c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
找到了一個更簡單的解決方案:
d1 |>
add_column(d1 |>
map2_dfc(v1, `*`) |>
rename_with(.cols = everything(),
.fn = ~paste0("pct_", .)))
uj5u.com熱心網友回復:
如果是按行,那么一個選項是c_across
library(dplyr)
library(stringr)
library(tibble)
new <- as_tibble(setNames(as.list(v1), names(d1)))
d1 %>%
rowwise %>%
mutate(c_across(everything()) * new) %>%
rename_with(~ str_c("pro_", .x), everything()) %>%
bind_cols(d1, .)
-輸出
1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
或者另一種選擇是map2
library(purrr)
map2_dfc(d1, v1, `*`) %>%
rename_with(~ str_c("pro_", .x), everything()) %>%
bind_cols(d1, .)
-輸出
c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
此外,使用 OP' 方法,它是一data.frame列。可以unpack編輯
library(tidyr)
d1 |>
mutate(pro = sweep(cur_data(), 2, v1, `*`)) |>
unpack(pro, names_sep = "_")
-輸出
# A tibble: 3 × 6
c1 c2 c3 pro_c1 pro_c2 pro_c3
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
編輯:基于@deschen 評論names_sep
uj5u.com熱心網友回復:
apply(. , 1, fun)這是通常范例的 dplyr 化版本:
d1 %>% apply(1, "*", v1) %>% t %>% cbind(d1, .)
c1 c2 c3 c1 c2 c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
如果您想在系結回起始資料幀之前將列名分配給矩陣,它會有點駭人聽聞:
d1 %>% apply(1, "*", v1) %>% t %>% `colnames<-`(., paste0("pro_", colnames(.))) %>% cbind(d1, .)
c1 c2 c3 pro_c1 pro_c2 pro_c3
1 1 4 7 1 8 21
2 2 5 8 2 10 24
3 3 6 9 3 12 27
uj5u.com熱心網友回復:
類似于@IRTFM 的解決方案,但不需要apply(...)
cbind(d1, t(t(d1)*v1))
## c1 c2 c3 c1 c2 c3
## 1 1 4 7 1 8 21
## 2 2 5 8 2 10 24
## 3 3 6 9 3 12 27
要么,
result <- cbind(d1, t(t(d1)*v1))
colnames(result) <- c(colnames(d1), paste0('pro_', colnames(d1)))
result
它給出了你想要的列名。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/454440.html
