R - ddply и инкрементный счетчик - PullRequest
2 голосов
/ 07 сентября 2011

Я использую ddply, чтобы разделить фрейм данных и отправить фрагменты в функцию.Перед строкой ddply я установил i=1.Затем внутри функции я увеличиваю i, чтобы каждый кусок данных получал новый номер.Однако когда я запускаю это, i сбрасывается в 1 при каждом вызове функции.Я предполагаю, что это потому, что i вне функции переназначается каждый раз, когда ddply отправляет новый кусок данных.Есть ли способ выйти за пределы функции и отправить этот номер вместе с данными?

EDIT :: Вот вызывающая строка:

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)
}

Ответы [ 2 ]

5 голосов
/ 07 сентября 2011

Это обычная проблема, когда вы, если вы настаиваете на этом, должны использовать <<- для глобального назначения:

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> 
2 голосов
/ 07 сентября 2011

Вы можете использовать assign, чтобы изменить значение глобальной переменной внутри вашей функции:

> x <- 10

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

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

Как видите, test1 не делает то, что вы ожидаете, тогда как test2 делает.

edit: Более краткий подход, который я только что обнаружил, прочитав руководство, заключается в использовании оператора "superassignment" <<-:

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

Руководство объясняет семантику простого присваивания в функции:

Обратите внимание, что любые обычные присваивания, выполняемые в функции, являются локальными и временными и теряются после выхода изфункция.Таким образом, присваивание X <- qr(X) не влияет на значение аргумента в вызывающей программе.

...