我想按一个特定的year
(按gender
分组)重新缩放df
中的所有变量(但year
和gender
):
set.seed(1)
df <- data.frame(gender = c(rep("m", 5), rep("f", 5)), year = rep(1:5, 2), var_a = 1:10, var_b = 0:9)
df
gender year var_a var_b
1 m 1 1 0
2 m 2 2 1
3 m 3 3 2
4 m 4 4 3
5 m 5 5 4
6 f 1 6 5
7 f 2 7 6
8 f 3 8 7
9 f 4 9 8
10 f 5 10 9
我可以使用以下方法生成期望的结果:
df %>% group_by(gender) %>% mutate(var_a = ifelse(year == 3, 0, var_a - var_a[year == 3])) %>%
mutate(var_b = ifelse(year == 3, 0, var_b - var_b[year == 3]))
gender year var_a var_b
<fct> <int> <dbl> <dbl>
1 m 1 -2 -2
2 m 2 -1 -1
3 m 3 0 0
4 m 4 1 1
5 m 5 2 2
6 f 1 -2 -2
7 f 2 -1 -1
8 f 3 0 0
9 f 4 1 1
10 f 5 2 2
但是,这不是一个选择,因为我的列太多了。
所以我尝试了(没有成功):
df %>% group_by(gender) %>% mutate_at(vars(-gender, -year), ifelse(year == 3, 0, var_a - var_a[year == 3]))
ifelse(year == 3,0,var_a-var_a [year == 3])中的错误:对象
找不到“年份”
我如何使用
mutate_at
在vars(-col_name)
(或替代方法)中排除列名,同时仍读取这些列中的数据?这与this one有关
最佳答案
如果在函数之前添加~
,则应获得所需的输出。
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
set.seed(1)
df <- data.frame(gender = c(rep("m", 5),
rep("f", 5)),
year = rep(1:5, 2), var_a = 1:10, var_b = 0:9)
df
#> gender year var_a var_b
#> 1 m 1 1 0
#> 2 m 2 2 1
#> 3 m 3 3 2
#> 4 m 4 4 3
#> 5 m 5 5 4
#> 6 f 1 6 5
#> 7 f 2 7 6
#> 8 f 3 8 7
#> 9 f 4 9 8
#> 10 f 5 10 9
df %>%
group_by(gender) %>%
mutate_at(vars(-gender, -year),
~ifelse(year == 3, 0, . - .[year == 3]))
#> # A tibble: 10 x 4
#> # Groups: gender [2]
#> gender year var_a var_b
#> <fct> <int> <dbl> <dbl>
#> 1 m 1 -2 -2
#> 2 m 2 -1 -1
#> 3 m 3 0 0
#> 4 m 4 1 1
#> 5 m 5 2 2
#> 6 f 1 -2 -2
#> 7 f 2 -1 -1
#> 8 f 3 0 0
#> 9 f 4 1 1
#> 10 f 5 2 2
由reprex package(v0.2.1)于2019-04-29创建
编辑:
在较早版本的dplyr中,您将使用
funs()
,但是从dplyr 0.8.0开始它已被弃用。df %>%
group_by(gender) %>%
mutate_at(vars(-gender, -year),
funs(ifelse(year == 3, 0, . - .[year == 3])))