2017-01-26 36 views
2

我有一個data.frame類似於此:在dplyr變異,如何引用多個類似命名的變量

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")

+0

使用'mutate_'而不是'mutate',你可以給表達式作爲字符串,並且用你希望的數據名稱做所有'gsub'和'paste'。 – snaut

+0

對,但在這種情況下,我會有字符串向量,對不對?我不認爲'mutate_'可以處理這個問題,或者我錯了嗎? – Alex

+0

你是對的,這適用於多個參數,而不適用於字符串的向量。你可以建立一個列名和表達式列表來評估和使用'do.call',但這可能不是最簡單的方法。 – snaut

回答

1

一種方式通過基礎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 
+0

感謝您的回覆。這在我的具體情況下不起作用,因爲變量並不總是數字。我將編輯原始問題以使其更清楚。 – Alex

+1

是的,有點小小的爭吵讓它適合我的確切數據。謝謝! – Alex

2

你可以使用下面的代碼。假設是,只有兩個總是相似名稱的變量。

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