2017-04-01 61 views
0

我們有一個數據框。帶有匿名函數的mutate_at

df <- data_frame(x = 1:5, y = 101:105) 

和其操作上的柱,並返回一個函數若干列

ff <- function(df, col) df %>% 
     mutate_at(col, funs(c1 = .*2, c2 = .*3, c3 = .*4)) 

如何可以替代硬編碼列名C1,C2,C3與從參數col例如構造名paste0(col, 1)

這樣

df %>% ff("x") 

返回與

# A tibble: 10 × 5 
     x  y x1 x2 x3 
    <int> <int> <dbl> <dbl> <dbl> 
1  1 100  2  3  4 
2  2 101  4  6  8 
3  3 102  6  9 12 
4  4 103  8 12 16 
5  5 104 10 15 20 
+1

非dplyr解決方案可以是簡單地'DF [paste0( 「X」,1:3)] < - DF $ X *代表(2:4中,每個=長度( df $ x))'(可以很容易地包裝成一個函數) –

回答

2

一個tibble您可以採取的rename_優勢,通過它,你可以很容易地構建名稱。在這裏,我將名稱設置爲與使用setNames的硬編碼名稱相匹配,然後重命名它們。

updatedFF <- function(df, col){ 
    colNames <- 
    setNames(
     paste0("c", 1:3) 
     , paste0(col, 1:3)) 

    df %>% 
    mutate_at(col, funs(c1 = .*2, c2 = .*3, c3 = .*4)) %>% 
    rename_(.dots = colNames) 
} 

df %>% updatedFF("x") 

# A tibble: 5 × 5 
     x  y x1 x2 x3 
    <int> <int> <dbl> <dbl> <dbl> 
1  1 101  2  3  4 
2  2 102  4  6  8 
3  3 103  6  9 12 
4  4 104  8 12 16 
5  5 105 10 15 20 

需要注意的是,如果你在一個以上的列名通過這將會失敗。這是因爲當你傳入一個列名稱時,已命名的函數會預先加上列名。你可以在你原有的ff功能看這個,如果你通過這兩個「X」和「Y」:

df %>% ff(c("x", "y")) 

# A tibble: 5 × 8 
     x  y x_c1 y_c1 x_c2 y_c2 x_c3 y_c3 
    <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1 101  2 202  3 303  4 404 
2  2 102  4 204  6 306  8 408 
3  3 103  6 206  9 309 12 412 
4  4 104  8 208 12 312 16 416 
5  5 105 10 210 15 315 20 420 

這種差異可能偶爾會出現問題,所以你可能想確保即使僅使用一列,也可以通過設置名稱使其包含列名來一致地處理它。在這裏,如果只有一列獲得通過,也只復位名稱和它設置它們相匹配時,多列在傳遞時發生的格式。

​​

有一列,其前(雖然工作原理非常類似於「 _c」包括):

df %>% moreComplexFF(c("x")) 

 x  y x_c1 x_c2 x_c3 
    <int> <int> <dbl> <dbl> <dbl> 
1  1 101  2  3  4 
2  2 102  4  6  8 
3  3 103  6  9 12 
4  4 104  8 12 16 
5  5 105 10 15 20 

有兩列,它留下的名字單獨(因此不會引發錯誤):

df %>% moreComplexFF(c("x", "y")) 

給出

 x  y x_c1 y_c1 x_c2 y_c2 x_c3 y_c3 
    <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1 101  2 202  3 303  4 404 
2  2 102  4 204  6 306  8 408 
3  3 103  6 206  9 309 12 412 
4  4 104  8 208 12 312 16 416 
5  5 105 10 210 15 315 20 420