英文:
how to derive new variables from existing using a vector of values
问题
这是我所拥有的数据:
temp <- tibble::tribble(
~x1, ~x2, ~x3, ~x4, ~x5,
1, 2, 3, 'AA', 'BB',
2, 3, 4, 'AB', 'CC',
3, 4, 5, 'AC', 'DD',
4, 5, 6, 'AD', 'EE',
5, 6, 7, 'AE', 'FF',
6, 7, 8, 'AF', 'GG'
) %>% dplyr::mutate(dplyr::across(x4,as.character), dplyr::across(x5,as.character))
我想通过与值为c(1,2,3)的temp_val向量相乘来导出新变量'px1'、'px2'、'px3'。
temp_val <- c(1,2,3)
我尝试了以下代码:
temp_val <- c(1,2,3)
nam1 <- c('px1','px2','px3')
temp5 <- temp %>% mutate(across(where(is.numeric), ~ . * temp_val, .names = '{nam1}'))
我得到了以下数据:
我的期望是将向量值视为列,并使用这些列创建多个变量。
英文:
here is the data what i have
temp <- tibble::tribble(
~x1, ~x2, ~x3, ~x4, ~x5,
1, 2, 3, 'AA', 'BB',
2, 3, 4, 'AB', 'CC',
3, 4, 5, 'AC', 'DD',
4, 5, 6, 'AD', 'EE',
5, 6, 7, 'AE', 'FF',
6, 7, 8, 'AF', 'GG'
) %>% dplyr::mutate(dplyr::across(x4,as.character), dplyr::across(x5,as.character))
I want to derive new variables 'px1', 'px2', 'px3' by multiplying with a vector temp_val with values c(1,2,3)
temp_val <- c(1,2,3)
I tried the below code
temp_val <- c(1,2,3)
nam1 <- c('px1','px2','px3')
temp5 <- temp %>% mutate(across(where(is.numeric), ~ . * temp_val, .names = '{nam1}'))
I get below data
my expectation, is to have vector values considered as columns and multiple variables with those columns
答案1
得分: 3
我们可以创建一个命名向量,然后根据从列名循环追加p
得到的名称,对temp_val
的元素进行子集化。
library(dplyr)
library(stringr)
names(temp_val) <- nam1
temp %>%
mutate(across(where(is.numeric), ~
.x * temp_val[str_c("p", cur_column())], .names = "p{.col}"))
-output
# A tibble: 6 × 8
x1 x2 x3 x4 x5 px1 px2 px3
<dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 1 2 3 AA BB 1 4 9
2 2 3 4 AB CC 2 6 12
3 3 4 5 AC DD 3 8 15
4 4 5 6 AD EE 4 10 18
5 5 6 7 AE FF 5 12 21
6 6 7 8 AF GG 6 14 24
或者如果名称顺序相同,可以使用map2
的另一种选项。
library(purrr)
map2_dfc(temp %>%
select(where(is.numeric)), temp_val, `*`) %>%
setNames(nam1)%>%
bind_cols(temp, .)
# A tibble: 6 × 8
x1 x2 x3 x4 x5 px1 px2 px3
<dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 1 2 3 AA BB 1 4 9
2 2 3 4 AB CC 2 6 12
3 3 4 5 AC DD 3 8 15
4 4 5 6 AD EE 4 10 18
5 5 6 7 AE FF 5 12 21
6 6 7 8 AF GG 6 14 24
英文:
We may create a named vector and then subset the elements of the temp_val
based on the name derived from appending p
to the column name looped (cur_column()
)
library(dplyr)
library(stringr)
names(temp_val) <- nam1
temp %>%
mutate(across(where(is.numeric), ~
.x * temp_val[str_c("p", cur_column())], .names = "p{.col}"))
-output
# A tibble: 6 × 8
x1 x2 x3 x4 x5 px1 px2 px3
<dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 1 2 3 AA BB 1 4 9
2 2 3 4 AB CC 2 6 12
3 3 4 5 AC DD 3 8 15
4 4 5 6 AD EE 4 10 18
5 5 6 7 AE FF 5 12 21
6 6 7 8 AF GG 6 14 24
Or another option if the names are in the same order, then use map2
library(purrr)
map2_dfc(temp %>%
select(where(is.numeric)), temp_val, `*`) %>%
setNames(nam1)%>%
bind_cols(temp, .)
# A tibble: 6 × 8
x1 x2 x3 x4 x5 px1 px2 px3
<dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 1 2 3 AA BB 1 4 9
2 2 3 4 AB CC 2 6 12
3 3 4 5 AC DD 3 8 15
4 4 5 6 AD EE 4 10 18
5 5 6 7 AE FF 5 12 21
6 6 7 8 AF GG 6 14 24
答案2
得分: 2
除了 @akrun 的回答之外,您还可以使用逐行计算:
library(dplyr)
library(tidyr)
temp <- tibble::tribble(
~x1, ~x2, ~x3, ~x4, ~x5,
1, 2, 3, 'AA', 'BB',
2, 3, 4, 'AB', 'CC',
3, 4, 5, 'AC', 'DD',
4, 5, 6, 'AD', 'EE',
5, 6, 7, 'AE', 'FF',
6, 7, 8, 'AF', 'GG'
) %>% dplyr::mutate(dplyr::across(x4, as.character), dplyr::across(x5, as.character))
temp_val <- c(1, 2, 3)
nam1 <- c('px1', 'px2', 'px3')
temp %>%
rowwise() %>%
transmute(newvars = list(c_across(where(is.numeric)) * temp_val)) %>%
unnest_wider(newvars) %>%
setNames(nam1) %>%
bind_cols(temp, .)
在 2023-01-08 由 reprex 包 (v2.0.1) 创建
英文:
In addition to @akrun's answer, you could also use a row-wise calculation:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tidyr)
temp <- tibble::tribble(
~x1, ~x2, ~x3, ~x4, ~x5,
1, 2, 3, 'AA', 'BB',
2, 3, 4, 'AB', 'CC',
3, 4, 5, 'AC', 'DD',
4, 5, 6, 'AD', 'EE',
5, 6, 7, 'AE', 'FF',
6, 7, 8, 'AF', 'GG'
) %>% dplyr::mutate(dplyr::across(x4,as.character), dplyr::across(x5,as.character))
temp_val <- c(1,2,3)
nam1 <- c('px1','px2','px3')
temp %>%
rowwise() %>%
transmute(newvars = list(c_across(where(is.numeric))*temp_val)) %>%
unnest_wider(newvars) %>%
setNames(nam1) %>%
bind_cols(temp, .)
#> # A tibble: 6 × 8
#> x1 x2 x3 x4 x5 px1 px2 px3
#> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 1 2 3 AA BB 1 4 9
#> 2 2 3 4 AB CC 2 6 12
#> 3 3 4 5 AC DD 3 8 15
#> 4 4 5 6 AD EE 4 10 18
#> 5 5 6 7 AE FF 5 12 21
#> 6 6 7 8 AF GG 6 14 24
<sup>Created on 2023-01-08 by the reprex package (v2.0.1)</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论