如何将一个列表的所有对象应用于一个改变dplyr TIBLE的函数?

如何将一个列表的所有对象应用于一个改变dplyr TIBLE的函数?,r,dplyr,R,Dplyr,我有一个变量的数据集,我想对其执行一些标准的突变(例如,求和、除法)。我有一个列表,它指定了我想要除以哪个变量的变量 我想知道是否有可能对列表中的所有名称应用一个自定义的mutate函数,对tibble进行迭代变异(即不创建像lappy那样的新tibble) 例如,我希望Sepal.Width和Petal.Length被Sepal.Length缩放(除以),并且类似于Sepal.Width scale\u variables\u by=list(萼片长度=c(“萼片宽度”、“花瓣长度”), 萼片

我有一个变量的数据集,我想对其执行一些标准的突变(例如,求和、除法)。我有一个列表,它指定了我想要除以哪个变量的变量

我想知道是否有可能对列表中的所有名称应用一个自定义的mutate函数,对tibble进行迭代变异(即不创建像
lappy
那样的新tibble)

例如,我希望
Sepal.Width
Petal.Length
Sepal.Length
缩放(除以),并且类似于
Sepal.Width

scale\u variables\u by=list(萼片长度=c(“萼片宽度”、“花瓣长度”),
萼片宽度=c(“花瓣宽度”,“花瓣长度”))
为此,我有两个功能。 第一个变量将一个变量按另一个变量进行缩放,并将新列重命名为
“original”\uu“div”\uu“scalar”

#按一个变量缩放另一个变量
按百分比缩放
重命名_at(变量(以“temp”结尾)、~paste(变量、分隔符、标量、,
sep=“”))
}
第二种方法获取一个列表,访问指定由特定变量缩放的所有变量,并按该变量缩放它们

#获取具有指定变量/标量组合的列表并按比例应用
#对他们来说
按列表%
按比例缩放(变量=输入列表[[scalar\u l]],scalar=scalar\u l)
}
将所有这些放在一起,其工作原理如下:

库(dplyr)
#按一个变量缩放另一个变量
按百分比缩放
重命名_at(变量(以“temp”结尾)、~paste(变量、分隔符、标量、,
sep=“”))
}
#获取具有指定变量/标量组合的列表,并按
#对他们来说
按列表%
按比例缩放(变量=输入列表[[scalar\u l]],scalar=scalar\u l)
}
比例变量列表(萼片长度=c(“萼片宽度”,“花瓣长度”),
萼片宽度=c(“花瓣宽度”,“花瓣长度”))
虹膜%>%
as_tible()%>%
scale_by_list(输入_list=scale_variables_by,scalar_l=“sepl.Length”)%>%
按列表缩放(输入列表=按变量缩放,标量l=“seval.Width”)%>%
选择(Sepal.Width\u div\u Sepal.Length,everything())
#>#A tible:150 x 9
#>萼片。宽\u div~萼片。长萼片。宽花瓣。长花瓣。宽
#>                                             
#>  1            0.686          5.1         3.5          1.4         0.2
#>  2            0.612          4.9         3            1.4         0.2
#>  3            0.681          4.7         3.2          1.3         0.2
#>  4            0.674          4.6         3.1          1.5         0.2
#>  5            0.72           5           3.6          1.4         0.2
#>  6            0.722          5.4         3.9          1.7         0.4
#>  7            0.739          4.6         3.4          1.4         0.3
#>  8            0.68           5           3.4          1.5         0.2
#>  9            0.659          4.4         2.9          1.4         0.2
#> 10            0.633          4.9         3.1          1.5         0.1
#> # ... 还有140多行和4个变量:物种,
#>花瓣长萼片长,
#>#花瓣宽(花瓣长)萼片宽(花瓣长)萼片宽)
由(v0.2.1)于2019-08-01创建

结果就是我想要的(我有四个新列,其中包含缩放变量),除了我想为列表中的所有对象调用
scale\u by\u list
,而不是手动为每个对象创建调用

lappy
可以做到这一点,但是它会在一个列表中创建多个不同的tibble,我想可以加入,但我觉得有更好的方法



我倾向于管道可移植性的解决方案:

按百分比缩放
重命名_at(变量(以“temp”结尾)、~paste(变量、分隔符、标量、,
sep=“”)%>%
选择(粘贴(变量、分隔符、标量、sep=“”))
}
虹膜%>%
捆扎(
名称(缩放变量)%>%
映射dfc(按列表缩放,df=as_tible(iris),
输入\列表=缩放\变量\按)

如果我理解正确,您就得到了
scale\u variables\u by
列表,并且对于列表中的每个元素,您都希望将其除以该列表的名称(或任何其他操作)。我们可以使用带有
Map

iris_df <- iris

new_names <- c(mapply(function(x, y) paste0(x, "_div_", y), 
                scale_variables_by, names(scale_variables_by)))

iris_df[new_names] <- do.call(cbind, Map(function(x, y) 
     iris_df[x]/iris_df[rep(y, length(x))], scale_variables_by, names(scale_variables_by)))


head(iris_df)

#Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Width_div_Sepal.Length
#1          5.1         3.5          1.4         0.2  setosa                       0.6863
#2          4.9         3.0          1.4         0.2  setosa                       0.6122
#3          4.7         3.2          1.3         0.2  setosa                       0.6809
#4          4.6         3.1          1.5         0.2  setosa                       0.6739
#5          5.0         3.6          1.4         0.2  setosa                       0.7200
#6          5.4         3.9          1.7         0.4  setosa                       0.7222


#  Petal.Length_div_Sepal.Length Petal.Width_div_Sepal.Width Petal.Length_div_Sepal.Width
#1                        0.2745                     0.05714                       0.4000
#2                        0.2857                     0.06667                       0.4667
#3                        0.2766                     0.06250                       0.4062
#4                        0.3261                     0.06452                       0.4839
#5                        0.2800                     0.05556                       0.3889
#6                        0.3148                     0.10256                       0.4359
这与以下方式使用
map2
相同

iris_df[new_names] <- purrr::map2_dfc(scale_variables_by, names(scale_variables_by),
                       ~iris_df[.x]/iris_df[rep(.y, length(.x))])

iris\u df[new_names]如果我理解正确,您已经得到了
scale_variables\u by
列表,并且对于列表中的每个元素,您希望将其除以(或任何其他操作)该列表的名称。我们可以使用带有
Map

iris_df <- iris

new_names <- c(mapply(function(x, y) paste0(x, "_div_", y), 
                scale_variables_by, names(scale_variables_by)))

iris_df[new_names] <- do.call(cbind, Map(function(x, y) 
     iris_df[x]/iris_df[rep(y, length(x))], scale_variables_by, names(scale_variables_by)))


head(iris_df)

#Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Width_div_Sepal.Length
#1          5.1         3.5          1.4         0.2  setosa                       0.6863
#2          4.9         3.0          1.4         0.2  setosa                       0.6122
#3          4.7         3.2          1.3         0.2  setosa                       0.6809
#4          4.6         3.1          1.5         0.2  setosa                       0.6739
#5          5.0         3.6          1.4         0.2  setosa                       0.7200
#6          5.4         3.9          1.7         0.4  setosa                       0.7222


#  Petal.Length_div_Sepal.Length Petal.Width_div_Sepal.Width Petal.Length_div_Sepal.Width
#1                        0.2745                     0.05714                       0.4000
#2                        0.2857                     0.06667                       0.4667
#3                        0.2766                     0.06250                       0.4062
#4                        0.3261                     0.06452                       0.4839
#5                        0.2800                     0.05556                       0.3889
#6                        0.3148                     0.10256                       0.4359
这与以下方式使用
map2
相同

iris_df[new_names] <- purrr::map2_dfc(scale_variables_by, names(scale_variables_by),
                       ~iris_df[.x]/iris_df[rep(.y, length(.x))])

iris_df[new_names]嗯,这确实有效,但你认为可以通过管道传输吗?目前,我在数据集上执行了一些这样的函数和其他过滤/变异,因此最好以管道方式使用这些函数。@tbbarr我认为这里没有必要使用管道,因为只有在有一系列操作要执行时才需要管道。在这里,一切都是在一个命令本身内完成的。我也在答案中添加了一个
purrr
变量。我倾向于使用的解决方案,因为我实际上需要它来进行管道处理,因为在这之前/之后我要执行一系列操作,就是更改
scale\u by\u list
函数,只选择它创建的列,然后将这些列绑定到现有的TIBLE(请参阅我的文章的编辑)。@tbbarr这样做行得通吗?
iris_df%>%bind_cols(缩放变量%>%imap_dfc(~iris_df[.x]/iris_df[rep(.y,length(.x)))
?你可以从那里继续你的管道。是的,这正是我想要的。谢谢,这确实行得通,但你看到我了吗