使用基R从dplyr::mutate_at()复制结果

使用基R从dplyr::mutate_at()复制结果,r,dplyr,R,Dplyr,我正在尝试使用base R复制dplyr::mutate_at()的结果。我自己对编写函数相当陌生,我想知道我提出的函数是否(a)合理,(b)如何在函数内部调用cbind()并保留菱形数据集中的所有变量 首先是dplyr::mutate_at()调用: require(tidyverse) diamonds %>% mutate_at(.funs = funs(relative = ./price), .vars = c("x", "y", "z")) # A tibble: 53

我正在尝试使用base R复制
dplyr::mutate_at()
的结果。我自己对编写函数相当陌生,我想知道我提出的函数是否(a)合理,(b)如何在函数内部调用
cbind()
并保留
菱形数据集中的所有变量

首先是
dplyr::mutate_at()
调用:

require(tidyverse)

diamonds %>% 
  mutate_at(.funs = funs(relative = ./price), .vars = c("x", "y", "z"))
# A tibble: 53,940 x 13
   #carat cut       color clarity depth table price     x     y     z x_relative y_relative z_relative
   #<dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>      <dbl>      <dbl>      <dbl>
 #1 0.23  Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43     0.0121     0.0122    0.00745
 #2 0.21  Premium   E     SI1      59.8    61   326  3.89  3.84  2.31     0.0119     0.0118    0.00709
 #3 0.23  Good      E     VS1      56.9    65   327  4.05  4.07  2.31     0.0124     0.0124    0.00706
 #4 0.290 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63     0.0126     0.0127    0.00787
 #5 0.31  Good      J     SI2      63.3    58   335  4.34  4.35  2.75     0.0130     0.0130    0.00821
 #6 0.24  Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48     0.0117     0.0118    0.00738
 #7 0.24  Very Good I     VVS1     62.3    57   336  3.95  3.98  2.47     0.0118     0.0118    0.00735
 #8 0.26  Very Good H     SI1      61.9    55   337  4.07  4.11  2.53     0.0121     0.0122    0.00751
 #9 0.22  Fair      E     VS2      65.1    61   337  3.87  3.78  2.49     0.0115     0.0112    0.00739
#10 0.23  Very Good H     VS1      59.4    61   338  4     4.05  2.39     0.0118     0.0120    0.00707
# ... with 53,930 more rows

管道操作符
%%>%%
隐式地将数据帧
菱形
作为第一个参数传递给
mutate_at()
。要模拟其行为,您需要对函数执行相同的操作。因为您要将整个数据帧传递给函数,所以您也可以将列名传递为
x

rel_fun <- function(.data, x, y){
  out <- .data[x] / y
  colnames(out) <- (paste(x, "relative", sep = "_"))
  out2 <- cbind(.data, out)
  out2
}

rel_fun( diamonds, c("x", "y", "z"), diamonds$price )    # Works as desired

rel\u-fun管道操作符
%%>%
隐式地将数据帧
菱形作为第一个参数传递给
mutate\u at()
。要模拟其行为,您需要对函数执行相同的操作。因为您要将整个数据帧传递给函数,所以您也可以将列名传递为
x

rel_fun <- function(.data, x, y){
  out <- .data[x] / y
  colnames(out) <- (paste(x, "relative", sep = "_"))
  out2 <- cbind(.data, out)
  out2
}

rel_fun( diamonds, c("x", "y", "z"), diamonds$price )    # Works as desired

rel_fun太好了!那么在函数中使用
data
会传递数据吗?我尝试了
函数(x,y,z){…}
,并在调用该函数时在
z
的位置添加了
diamonds
,但没有成功。另一个问题,为什么我不能简单地做
diamonds
,而必须做
diamonds$price
?这里可能会混淆
diamonds
中的x,y,z列名和
rel_fun
的参数x,y,z。通常,可以根据需要调用函数参数。您只需要在函数中使用相同的名称。例如,您可以使用
z
代替
.data
。但是,您可以相应地替换它的用法(例如,
z[x]
代替
.data[x]
),这太棒了!那么在函数中使用
data
会传递数据吗?我尝试了
函数(x,y,z){…}
,并在调用该函数时在
z
的位置添加了
diamonds
,但没有成功。另一个问题,为什么我不能简单地做
diamonds
,而必须做
diamonds$price
?这里可能会混淆
diamonds
中的x,y,z列名和
rel_fun
的参数x,y,z。通常,可以根据需要调用函数参数。您只需要在函数中使用相同的名称。例如,您可以使用
z
代替
.data
。但随后您将相应地替换其用法(例如,
z[x]
代替
.data[x]
rel_fun <- function(x, y){
  out <- x / y
  colnames(out) <- (paste(colnames(x), "relative", sep = "_"))
  out2 <- cbind(x, out)
  out2
}

df_out3 <- rel_fun(diamonds[c("x", "y", "z")], diamonds$price)
head(df_out3)
#     x    y    z x_relative y_relative  z_relative
#1 3.95 3.98 2.43 0.01211656 0.01220859 0.007453988
#2 3.89 3.84 2.31 0.01193252 0.01177914 0.007085890
#3 4.05 4.07 2.31 0.01238532 0.01244648 0.007064220
#4 4.20 4.23 2.63 0.01257485 0.01266467 0.007874251
#5 4.34 4.35 2.75 0.01295522 0.01298507 0.008208955
#6 3.94 3.96 2.48 0.01172619 0.01178571 0.007380952  
rel_fun <- function(.data, x, y){
  out <- .data[x] / y
  colnames(out) <- (paste(x, "relative", sep = "_"))
  out2 <- cbind(.data, out)
  out2
}

rel_fun( diamonds, c("x", "y", "z"), diamonds$price )    # Works as desired