R - ddply并递增计数器

问题描述:

我正在使用ddply拆分数据帧并将块发送到函数。在ddply行之前,我设置了i=1。然后在函数内部我递增i,以便每个数据块都有一个新的数字。但是,当我运行此功能时,每次调用该功能时,i都将被重置为1。我认为这是因为外部功能i正在重新分配,每次ddply发送一个新的数据块。有没有一种方法可以在函数外进行递增并将数字与数据一起发送?R - ddply并递增计数器

编辑:: 这里是主叫用户线:

rseDF <- ddply(rseDF, .(TestCompound), .fun = setTheSet) 

下面是函数:

##Set The Set Column 
setTheSet <- function(df) { 
if (df[,"TestCompound"] == "DNS000000001") df[,"Set"] <- "Control" 
else {df[,"Set"] <- i 
i <<- i+1} 
return(df) 
} 
+1

这听起来有些奇怪的事情做'ddply' 。也许如果你扩展一点你的用例并提供一个最小的例子,我们可以建议替代设计模式。 (这听起来像你真的忙于循环,在这种情况下'ldply'可能更合适?) – Andrie

+0

谢谢安德烈。我实际上没有使用循环。使用'ddply'的全部原因是为了消除for循环。该函数只是创建一个列,并为所有成员放入“i”。据我所知,这是ddply()制作的“Split-Apply-Combine”策略。 – James

这仅仅是一个正常的范围界定问题,即你,如果你坚持这样的话,需要使用<<-全球分配:

R> library(plyr)     ## load plyr 
R> i <- 1       ## set counter 
R> DF <- data.frame(a=rep(letters[1:3], each=3), b=1:9) 
R> DF        ## boring but simple data frame 
    a b 
1 a 1 
2 a 2 
3 a 3 
4 b 4 
5 b 5 
6 b 6 
7 c 7 
8 c 8 
9 c 9 
R> ddply(DF, .(a), function(x) mean(x$b))  ## summarized 
    a V1 
1 a 2 
2 b 5 
3 c 8 
R> ddply(DF, .(a), function(x) { i <<- i + 1; data.frame(i=i, res=mean(x$b)) }) 
    a i res 
1 a 2 2 
2 b 3 5 
3 c 4 8 
R> 
+0

谢谢德克。我认为R会为此提供一个简单的解决方案,但Google在寻找具体答案时似乎几乎无用。 – James

+0

快乐 - 另外,如果您通过http://rseek.org网站进行查询,或者只是添加诸如“r-help”之类的字词或仅限于gmane.org列表存档或... –

+1

@ dirk也是,如果您使用Gmail并已登录,并点击足够多的R相关链接,它们将会升级为您的帐户。当我开始时,我发现很难找到R相关的链接,但现在他们几乎总是处于顶端 – richiemorrisroe

你可以使用assign全局变量的值从你的函数中更改:

> x <- 10 

> test1 <- function() { x <- 3 } 
> test1() 
> x 
[1] 10 

> test2 <- function() { assign('x', 3, envir = .GlobalEnv) } 
> test2() 
> x 
[1] 3 

正如你所看到的,test1不会做你期望的,而test2呢。

编辑:更简洁,我已经通过阅读说明书发现的方法是使用“超赋值”操作符<<-

> test3 <- function() { x <<- 17 } 
> test3() 
> x 
[1] 17 

手动explains的简单分配中的语义功能:

请注意,在该功能内完成的任何普通分配都是本地 和临时的,并在退出该功能后丢失。因此, 分配X <- qr(X)不会影响调用程序中参数的值。