在 dplyr mutate 中,如何引用多个名称相似的变量
In dplyr mutate, how to reference multiple similarly named variables
我有一个 data.frame
类似于这个:
library(tidyverse)
df <- data.frame(
var_1_a = 1:100,
var_1_b = 101:200,
var_two_a = 5:104,
var_two_b = 1:100
)
head(df)
var_1_a var_1_b var_two_a var_two_b
1 1 101 5 1
2 2 102 6 2
3 3 103 7 3
4 4 104 8 4
5 5 105 9 5
6 6 106 10 6
我想求同名变量的不同。因为这里只有两个,所以用类似的东西很容易做到:
df %>%
mutate(var_1_new = var_1_a - var_1_b,
var_two_new = var_two_a - var_two_b)
但在真实数据中我有大约一百个这样的数据。比全部输入更简单的方法是什么?
PS - 如果它更容易,我有一个包含所有变量的列表(例如 mylist <- list("var_1", "var_two")
一种通过 base R 实现的方法,
ind <- unique(stringr::word(names(df), 2, sep = '_'))
m1 <- sapply(ind, function(i) Reduce(`-`, (df[stringr::word(names(df), 2, sep = '_') %in% i])))
#which gives,
head(m1)
# [,1] [,2]
#[1,] -100 4
#[2,] -100 4
#[3,] -100 4
#[4,] -100 4
#[5,] -100 4
#[6,] -100 4
为了达到你想要的效果,
final_df <- cbind(df, setNames(data.frame(m1), c(paste0('var_', ind, '_new'))))
# var_1_a var_1_b var_two_a var_two_b var_1_new var_two_new
#1 1 101 5 1 -100 4
#2 2 102 6 2 -100 4
#3 3 103 7 3 -100 4
#4 4 104 8 4 -100 4
#5 5 105 9 5 -100 4
#6 6 106 10 6 -100 4
您可以使用以下代码。假设,总是只有两个名称相似的变量。
mylist <- list("var_1", "var_two")
get_similar_names <- function(x) grep(x,names(df))
get_diff <- function(x) Reduce(`-`, subset(df,select=x) )
matches <- lapply(mylist, get_similar_names )
out <- lapply(matches, get_diff)
names(out) <- paste0(mylist,"_new")
out.df <- data.frame(out)
head(out.df)
var_1_new var_two_new
1 -100 4
2 -100 4
3 -100 4
4 -100 4
5 -100 4
6 -100 4
我有一个 data.frame
类似于这个:
library(tidyverse)
df <- data.frame(
var_1_a = 1:100,
var_1_b = 101:200,
var_two_a = 5:104,
var_two_b = 1:100
)
head(df)
var_1_a var_1_b var_two_a var_two_b
1 1 101 5 1
2 2 102 6 2
3 3 103 7 3
4 4 104 8 4
5 5 105 9 5
6 6 106 10 6
我想求同名变量的不同。因为这里只有两个,所以用类似的东西很容易做到:
df %>%
mutate(var_1_new = var_1_a - var_1_b,
var_two_new = var_two_a - var_two_b)
但在真实数据中我有大约一百个这样的数据。比全部输入更简单的方法是什么?
PS - 如果它更容易,我有一个包含所有变量的列表(例如 mylist <- list("var_1", "var_two")
一种通过 base R 实现的方法,
ind <- unique(stringr::word(names(df), 2, sep = '_'))
m1 <- sapply(ind, function(i) Reduce(`-`, (df[stringr::word(names(df), 2, sep = '_') %in% i])))
#which gives,
head(m1)
# [,1] [,2]
#[1,] -100 4
#[2,] -100 4
#[3,] -100 4
#[4,] -100 4
#[5,] -100 4
#[6,] -100 4
为了达到你想要的效果,
final_df <- cbind(df, setNames(data.frame(m1), c(paste0('var_', ind, '_new'))))
# var_1_a var_1_b var_two_a var_two_b var_1_new var_two_new
#1 1 101 5 1 -100 4
#2 2 102 6 2 -100 4
#3 3 103 7 3 -100 4
#4 4 104 8 4 -100 4
#5 5 105 9 5 -100 4
#6 6 106 10 6 -100 4
您可以使用以下代码。假设,总是只有两个名称相似的变量。
mylist <- list("var_1", "var_two")
get_similar_names <- function(x) grep(x,names(df))
get_diff <- function(x) Reduce(`-`, subset(df,select=x) )
matches <- lapply(mylist, get_similar_names )
out <- lapply(matches, get_diff)
names(out) <- paste0(mylist,"_new")
out.df <- data.frame(out)
head(out.df)
var_1_new var_two_new
1 -100 4
2 -100 4
3 -100 4
4 -100 4
5 -100 4
6 -100 4