当使用 plyr
时,我经常发现将 adply
用于标量函数是很有用的,我必须将其应用于每一行 .
例如
data(iris)
library(plyr)
head(
adply(iris, 1, transform , Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
6 5.4 3.9 1.7 0.4 setosa 5.4
现在我正在使用 dplyr
,我想知道是否有一个整洁/自然的方式来做到这一点?因为这是 NOT 我想要的:
library(dplyr)
head(
mutate(iris, Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 7.9
2 4.9 3.0 1.4 0.2 setosa 7.9
3 4.7 3.2 1.3 0.2 setosa 7.9
4 4.6 3.1 1.5 0.2 setosa 7.9
5 5.0 3.6 1.4 0.2 setosa 7.9
6 5.4 3.9 1.7 0.4 setosa 7.9
6 回答
惯用的方法是创建一个适当的矢量化函数 .
R
提供适合的pmax
,但它也提供了Vectorize
作为mapply
的包装,允许您创建任意函数的矢量化任意版本 .请注意,在C / C中实现矢量化会更快,但是没有
magicPony
包可以为您编写函数 .扩展BrodieG的答案,
如果函数返回多行,则必须使用
do()
而不是mutate()
. 然后将它组合回来,使用dplyr
包中的rbind_all()
.在
dplyr
versiondplyr_0.1.2
中,在group_by()
子句中使用1:n()
对我不起作用 . 希望很快Hadley will implement rowwise() .测试性能,
它有以下结果:
您需要按行分组:
这就是
1
在adply
中所做的 .像这样的东西?
更新2017-08-03
写完之后,哈德利又改变了一些东西 . 过去在purrr中的函数现在在a new mixed package called purrrlyr中,描述为:
因此,您需要安装load包以使下面的代码工作 .
原帖
Hadley经常改变他们对我们应该使用的东西的想法,但我认为我们应该切换到 purrr 中的函数来获得by行功能 . 至少,它们提供相同的功能,并且与 plyr 的
adply
具有几乎相同的界面 .有两个相关的函数,
by_row
和invoke_rows
. 我的理解是,当你想循环遍历行并将结果添加到data.frame时,你使用by_row
. 当循环遍历data.frame的行并将每个col作为参数传递给函数时,将使用invoke_rows
. 我们只会使用第一个 .例子
这让我们可以看到内部结构(所以我们可以看到我们正在做什么),这与使用
adply
进行操作相同 .默认情况下,
by_row
根据输出添加列表列:得到:
如果我们返回一个
data.frame
,我们得到一个data.frame
的列表:得到:
我们如何添加函数的输出由
.collate
param控制 . 无论我们是使用行还是列,都很重要 .两者都产生:
如果我们输出一行有1行的data.frame,那么我们使用的只是轻微的:
两者都给:
除了第二个具有名为
.row
的列而第一个没有 .最后,如果我们的输出长度为长度1,无论是
vector
还是带有行的data.frame
,那么我们是否使用.collate
的行或列来确定:分别产生:
所以,底线 . 如果需要
adply(.margins = 1, ...)
功能,可以使用by_row
.截至dplyr 0.2(我认为)
rowwise()
已实现,因此这个问题的答案变为: