如何将一个列表的所有对象应用于一个改变dplyr TIBLE的函数?
我有一个变量的数据集,我想对其执行一些标准的突变(例如,求和、除法)。我有一个列表,它指定了我想要除以哪个变量的变量 我想知道是否有可能对列表中的所有名称应用一个自定义的mutate函数,对tibble进行迭代变异(即不创建像如何将一个列表的所有对象应用于一个改变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(“萼片宽度”、“花瓣长度”), 萼片
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)))
?你可以从那里继续你的管道。是的,这正是我想要的。谢谢,这确实行得通,但你看到我了吗