Pie*_*aix 11 r nested-loops mutation dplyr purrr
我有一个国家和年份级别的面板数据集,我想根据现有变量创建两个新变量。
| 年 | 国家 | 变量1 | 变量2 | 变量3 | 变种4 | 平均值_var1 | relmean_var1 |
|---|---|---|---|---|---|---|---|
| 1910年 | 德国大学 | 1 | 4 | 10 | 6 | 3 | 0.333 |
| 1911年 | 德国大学 | 2 | 3 | 11 | 7 | 1.5 | 1.3333 |
| 1910年 | 法国航空协会 | 5 | 6 | 8 | 9 | 3 | 1.66667 |
| 1911年 | 法国航空协会 | 1 | 4 | 10 | 9 | 1.5 | .66667 |
我想做的是创建两个新的变量集:(1)每年(跨国家)平均值的变量集和(2)相对于年平均值的国家/地区值的变量集。例如,对于 var1(1) 将产生mean_var1和(2)relmean_var1,我希望这些用于所有其他变量。数据集中总共有超过 1000 个变量,但我只会将此函数应用于大约 6 个变量。
我有适用于第一部分的代码,但我想将其尽可能有效地与第二部分结合起来。
library(dplyr)
library(purrr)
df<- df%>%
group_by(year) %>%
mutate_at(.funs = list(mean = ~mean(.)), .vars = c("var1", "var1", "var1", "var4"))
Run Code Online (Sandbox Code Playgroud)
此代码生成名为 var1_mean 的新变量(我更喜欢mean_var1:如何更改此名称?)
对于第二步,我尝试过:
df <- df %>%
map2_dfr(.x = d.test %>%
select(var1, var2),
.y = d.test %>%
select(var1_mean, var2_mean),
~ .x / .y) %>%
setNames(c("relmean_var1", "relmean_var2"))
Run Code Online (Sandbox Code Playgroud)
我收到错误
“select(., var1, var2) 中出现错误:未找到对象‘d.test’。”
。(我从这个问题中得到了这个设置)
我也尝试过:
map2(var1, var1_mean, ~ df[[.x]] / df[[.y]]) %>%
set_names(cols) %>%
bind_cols(df, .)
Run Code Online (Sandbox Code Playgroud)
并得到了
“map2(var1, var1_mean, ~df[[.x]]/df[[.y]]) 中出现错误:未找到对象“var1”
结合这两个目标的最佳方式是什么?理想情况下,(1) 的命名方案为mean_var1,(2) 的命名方案为relmean_var1
编辑:输入数据框应如下所示:
data <- tibble::tribble(
~year, ~country, ~var1, ~var2, ~var3, ~var.4,
1910L, "GER", 1L, 4L, 10L, 6L,
1911L, "GER", 2L, 3L, 11L, 7L,
1910L, "FRA", 5L, 6L, 8L, 9L,
1911L, "FRA", 1L, 4L, 10L, 9L
)
Run Code Online (Sandbox Code Playgroud)
输出数据帧应如下所示(对于所有变量,仅以 var1 为例,但 var2 到 var4 的格式应相同):
datanew <- tibble::tribble(
~year, ~country, ~var1, ~var2, ~var3, ~var.4, ~mean_var1 , ~relmean_var1
1910L, "GER", 1L, 4L, 10L, 6L, 3L, .3333L,
1911L, "GER", 2L, 3L, 11L, 7L, 1.5L, 1.3333L,
1910L, "FRA", 5L, 6L, 8L, 9L, 3L, 1.6667L,
1911L, "FRA", 1L, 4L, 10L, 9L 1.5L, .6667L,
)
Run Code Online (Sandbox Code Playgroud)
Ben*_*Ben 19
这在长格式中可能会更容易,但这里有一个您可以追求的宽数据选项。
使用最新版本,dplyr您可以mutate across并包含.names参数来定义您希望新列的外观。
library(tidyverse)
my_col <- c("var1", "var2", "var3", "var4")
df %>%
group_by(year) %>%
mutate(across(my_col, mean, .names = "mean_{col}")) %>%
mutate(across(my_col, .names = "relmean_{col}") / across(paste0("mean_", my_col)))
Run Code Online (Sandbox Code Playgroud)
输出
year country var1 var2 var3 var4 mean_var1 mean_var2 mean_var3 mean_var4 relmean_var1 relmean_var2 relmean_var3 relmean_var4
<int> <chr> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1910 GER 1 4 10 6 3 5 9 7.5 0.333 0.8 1.11 0.8
2 1911 GER 2 3 11 7 1.5 3.5 10.5 8 1.33 0.857 1.05 0.875
3 1910 FRA 5 6 8 9 3 5 9 7.5 1.67 1.2 0.889 1.2
4 1911 FRA 1 4 10 9 1.5 3.5 10.5 8 0.667 1.14 0.952 1.12
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13376 次 |
| 最近记录: |