mutate_at,带有命名的匿名函数

时间:2017-04-01 21:47:36

标签: r dplyr

我们有一个数据框。

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

和一个对列进行操作并返回多个列的函数

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

如何使用从参数col构造的名称替换硬编码列名称c1,c2,c3,例如paste0(col, 1)

这样

df %>% ff("x")

使用

返回一个tibble
# 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 个答案:

答案 0 :(得分:2)

您可以利用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

请注意,如果传入多个列名,则会失败。这是因为当您传入单个列名称时,已经使用列名称添加了命名函数。如果你同时通过&#34; x&#34;你可以在你原来的ff函数中看到这个。和&#34; y&#34;:

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

这种差异有时会导致问题,因此您可能希望通过将名称设置为包含列名来确保一致处理,即使只使用了一列。这里,它仅在只传递一列时重置名称,并将它们设置为与传入多列时发生的格式相匹配。

moreComplexFF <- function(df, col){
  if(length(col) == 1){
    colNames <-
      setNames(
        paste0("c", 1:3)
        , paste0(col, "_c", 1:3) )
  } else{
    colNames = NULL
  }

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

使用一列,它的工作方式与之前类似(尽管使用&#34; _c&#34;包含在内):

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