我想将列表a中的每一列除以列表b中的对应列,然后将该比率作为新的列返回到已存在的数据框中。
我想出了使用以下代码的一般方法(以Diamonds包为例):
library(tidyverse)
results <- list(
lst("depth", "table", "price"),
lst("x", "y", "z")
) %>%
pmap_dfc(~diamonds %>% mutate(var = !!sym(.x)/!!sym(.y))) %>%
select(c(1:ncol(diamonds)), matches("var")) %>%
rename(new1 = var,
new2 = var1,
new3 = var2)
我的问题是,这将为我创建的每个新变量复制整个数据框,然后我需要取消选择这些重复的列。这不是这里的问题,但是可能是当我需要使用1)更多变量和/或2)较大数据框来做到这一点时。
关于如何仅创建新列并将其绑定到菱形数据框的任何建议(即避免在我的代码中使用select
函数)?
编辑
期望的结果是上面results
对象中当前的内容(粘贴在下面)–在我的代码中到达那里的过程对我来说是错误的。
> results
# A tibble: 53,940 x 13
carat cut color clarity depth table price x y z new1 new2 new3
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 15.6 13.8 134.
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 15.4 15.9 141.
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 14.0 16.0 142.
4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63 14.9 13.7 127.
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 14.6 13.3 122.
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48 15.9 14.4 135.
7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47 15.8 14.3 136.
8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53 15.2 13.4 133.
9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 16.8 16.1 135.
10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39 14.8 15.1 141.
# ... with 53,930 more rows
答案 0 :(得分:1)
您可以分别生成这三个新列。由于顺序相同,因此您可以使用bind_cols
进行连接。
我只是想避免使用中间变量,所以我在管道中编写了所有内容。
diamonds %>%
bind_cols(
list(
lst("depth", "table", "price"),
lst("x", "y", "z")
) %>%
pmap_dfc(~diamonds[[.x]]/diamonds[[.y]]) %>%
{
colnames(.) <- c("var1","var2","var3")
return(.)
}
)
# A tibble: 53,940 x 13
carat cut color clarity depth table price x y z var1 var2 var3
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 15.6 13.8 134.
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 15.4 15.9 141.
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 14.0 16.0 142.
4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63 14.9 13.7 127.
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 14.6 13.3 122.
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48 15.9 14.4 135.
7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47 15.8 14.3 136.
8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53 15.2 13.4 133.
9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 16.8 16.1 135.
10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39 14.8 15.1 141.
# ... with 53,930 more rows
答案 1 :(得分:1)
只需transmute()
,然后将新列绑定到原始df:
library(tidyverse)
results <- list(
lst("depth", "table", "price"),
lst("x", "y", "z")
) %>%
pmap_dfc(~diamonds %>% transmute(var = !!sym(.x)/!!sym(.y))) %>%
bind_cols(diamonds, .)
答案 2 :(得分:0)
一种解决方案是组成未捕获的表达式以捕获所需的计算,然后将这些表达式直接传递给mutate:
# Inputs
a <- c("depth", "table", "price")
b <- c("x", "y", "z")
# Compose unevaluated expressions
e <- map2( a, b, ~expr(!!sym(.x)/!!sym(.y)) )
# Pass them to mutate using unquote-splice
R <- diamonds %>% mutate( !!!set_names(e, c("new1","new2","new3")) )
# Compare to desired output
all_equal( R, results ) # TRUE