An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20090518/20706c3a/attachment-0001.pl>
Generic 'diff'
9 messages · Stavros Macrakis, Wacek Kusnierczyk, Gabor Grothendieck
You can define a new class for the object diff operates on and then define your own diff method for that. For some examples see: methods(diff)
On Mon, May 18, 2009 at 4:24 PM, Stavros Macrakis <macrakis at alum.mit.edu> wrote:
I would like to apply a function 'f' to the lagged version of a vector and the vector itself. This is easy to do explicitly: ? ? ?mapply( f, v[-1], v[-length(v)] ) or in the case of a pointwise vector function, simply ? ? ?f( v[-1], v[-length(v)] ) This is essentially the same as 'diff' but with an arbitrary function, not '-'. Is there a standard way to do this? Is there any particular reason that 'diff' should not have an 'f' argument? ? ? ? ? ? ?-s ? ? ? ?[[alternative HTML version deleted]]
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20090518/ad0b1b27/attachment-0001.pl>
I understood what you were asking but R is an oo language so that's the model to use to do this sort of thing.
On Mon, May 18, 2009 at 5:48 PM, Stavros Macrakis <macrakis at alum.mit.edu> wrote:
I guess I wasn't very clear.? The goal is not to define diff on a different object type, but to have a different 'subtraction' operator with the same lag logic.? An easy example would be quotient instead of subtraction. Of course I could do that by simply cutting and pasting diff.default and replacing '-'(a,b) with f(a,b), but it's cleaner to use a standard function if there is one. ????????? -s On Mon, May 18, 2009 at 5:05 PM, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
You can define a new class for the object diff operates on and then define your own diff method for that. For some examples see: methods(diff) On Mon, May 18, 2009 at 4:24 PM, Stavros Macrakis <macrakis at alum.mit.edu> wrote:
I would like to apply a function 'f' to the lagged version of a vector and the vector itself. This is easy to do explicitly: ? ? ?mapply( f, v[-1], v[-length(v)] ) or in the case of a pointwise vector function, simply ? ? ?f( v[-1], v[-length(v)] ) This is essentially the same as 'diff' but with an arbitrary function, not '-'. Is there a standard way to do this? Is there any particular reason that 'diff' should not have an 'f' argument? ? ? ? ? ? ?-s ? ? ? ?[[alternative HTML version deleted]]
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20090518/704de0b7/attachment-0001.pl>
Stavros Macrakis wrote:
On Mon, May 18, 2009 at 6:00 PM, Gabor Grothendieck <ggrothendieck at gmail.com
wrote:
I understood what you were asking but R is an oo language so
that's the model to use to do this sort of thing.
I am not talking about creating a new class with an analogue to the subtraction function. I am talking about a function which applies another function to a sequence and its lagged version. Functional arguments are used all over the place in R's base package (Xapply, sweep, outer, by, not to mention Map, Reduce, Filter, etc.) and they seem perfectly natural here.
perhaps 'diff' would not be the best name, something like 'lag' would be
better for the more generic function, but 'lag' is already taken.
i agree it would be reasonable to have diff (lag) to accept an extra
argument for the function to be applied. the solution of wrapping the
vector into a new class to be diff'ed with a non-default diff does not
seem to make much sense, as (a) what you seem to want is to custom-diff
plain vectors, (b) to keep the diff family coherent, you'd need to
upgrade the other diffs to have the extra argument anyway.
as you say, it's trivial to implement an extended diff, say difff,
reusing code from diff:
difff = function(x, ...)
UseMethod('difff')
difff.default = function(x, lag=1, differences=1, fun=`-`, ...) {
ismat = is.matrix(x)
xlen = if (ismat) dim(x)[1L] else length(x)
if (length(lag) > 1L || length(differences) > 1L || lag < 1L ||
differences < 1L)
stop("'lag' and 'differences' must be integers >= 1")
if (lag * differences >= xlen) return(x[0])
r = unclass(x)
i1 = -1L:-lag
if (ismat)
for (i in 1L:differences)
r = fun(r[i1, , drop = FALSE], r[-nrow(r):-(nrow(r) - lag +
1), , drop = FALSE])
else
for (i in 1L:differences) r = fun(r[i1],
r[-length(r):-(length(r) - lag + 1)])
class(r) = oldClass(x)
r }
now, this naive version seems to work close to what you'd like:
difff(1:4)
# 1 1 1
difff(1:4, fun=`+`)
# 3 5 7
it might be useful if the original diff were working this way.
vQ
Wacek Kusnierczyk wrote:
Stavros Macrakis wrote:
[...]
I am not talking about creating a new class with an analogue to the
subtraction function. I am talking about a function which applies another
function to a sequence and its lagged version.
Functional arguments are used all over the place in R's base package
(Xapply, sweep, outer, by, not to mention Map, Reduce, Filter, etc.) and
they seem perfectly natural here.
[...]
as you say, it's trivial to implement an extended diff, say difff,
reusing code from diff:
difff = function(x, ...)
UseMethod('difff')
difff.default = function(x, lag=1, differences=1, fun=`-`, ...) {
ismat = is.matrix(x)
xlen = if (ismat) dim(x)[1L] else length(x)
if (length(lag) > 1L || length(differences) > 1L || lag < 1L ||
differences < 1L)
stop("'lag' and 'differences' must be integers >= 1")
btw., the error message here is confusing:
lag = 1:2
diff(1:10, lag=lag)
# Error in diff.default(1:10, lag = lag) :
# 'lag' and 'differences' must be integers >= 1
is.integer(lag)
# TRUE
all(lag >= 1)
# TRUE
what is meant is that lag and differences must be atomic 1-element
vectors of positive integers. or rather integer-representing numerics:
lag = 1
diff(1:5, lag=1)
# fine
is.integer(lag)
# FALSE
(the usual confusion between 'integer' as the underlying representation
and 'integer' as the represented number.)
vQ
Wacek Kusnierczyk wrote:
btw., the error message here is confusing:
lag = 1:2
diff(1:10, lag=lag)
# Error in diff.default(1:10, lag = lag) :
# 'lag' and 'differences' must be integers >= 1
is.integer(lag)
# TRUE
all(lag >= 1)
# TRUE
what is meant is that lag and differences must be atomic 1-element
vectors of positive integers. or rather integer-representing numerics:
lag = 1
diff(1:5, lag=1)
# fine
is.integer(lag)
# FALSE
... and even non-integer-representing non-integers are fine:
diff(1:5, lag=pi)
# 3 3
vQ
Note that this could be done like this for ordinary vectors:
x <- seq(1:4)^2
apply(embed(x, 2), 1, function(x, f) f(rev(x)), f = diff)
[1] 3 5 7
apply(embed(x, 2), 1, function(x, f) f(rev(x)), f = sum)
[1] 5 13 25 or a method to rollapply in zoo could be added for ordinary vectors. Here it is applied to zoo objects:
library(zoo) rollapply(zoo(x), 2, diff)
1 2 3 3 5 7
rollapply(zoo(x), 2, sum)
1 2 3 5 13 25 On Tue, May 19, 2009 at 4:23 AM, Wacek Kusnierczyk
<Waclaw.Marcin.Kusnierczyk at idi.ntnu.no> wrote:
Stavros Macrakis wrote:
On Mon, May 18, 2009 at 6:00 PM, Gabor Grothendieck <ggrothendieck at gmail.com
wrote:
I understood what you were asking but R is an oo language so that's the model to use to do this sort of thing.
I am not talking about creating a new class with an analogue to the subtraction function. ?I am talking about a function which applies another function to a sequence and its lagged version. Functional arguments are used all over the place in R's base package (Xapply, sweep, outer, by, not to mention Map, ?Reduce, Filter, etc.) and they seem perfectly natural here.
perhaps 'diff' would not be the best name, something like 'lag' would be
better for the more generic function, but 'lag' is already taken.
i agree it would be reasonable to have diff (lag) to accept an extra
argument for the function to be applied. ?the solution of wrapping the
vector into a new class to be diff'ed with a non-default diff does not
seem to make much sense, as (a) what you seem to want is to custom-diff
plain vectors, (b) to keep the diff family coherent, you'd need to
upgrade the other diffs to have the extra argument anyway.
as you say, it's trivial to implement an extended diff, say difff,
reusing code from diff:
? ?difff = function(x, ...)
? ? ? UseMethod('difff')
? ?difff.default = function(x, lag=1, differences=1, fun=`-`, ...) {
? ? ? ismat = is.matrix(x)
? ? ? xlen = if (ismat) dim(x)[1L] else length(x)
? ?if (length(lag) > 1L || length(differences) > 1L || lag < 1L ||
differences < 1L)
? ? ? stop("'lag' and 'differences' must be integers >= 1")
? ?if (lag * differences >= xlen) return(x[0])
? ?r = unclass(x)
? ?i1 = -1L:-lag
? ?if (ismat)
? ? ? ?for (i in 1L:differences)
? ? ? ? ? ?r = fun(r[i1, , drop = FALSE], r[-nrow(r):-(nrow(r) - lag +
1), , drop = FALSE])
? ?else
? ? ? ?for (i in 1L:differences) r = fun(r[i1],
r[-length(r):-(length(r) - lag + 1)])
? ?class(r) = oldClass(x)
? ?r }
now, this naive version seems to work close to what you'd like:
? ?difff(1:4)
? ?# 1 1 1
? ?difff(1:4, fun=`+`)
? ?# 3 5 7
it might be useful if the original diff were working this way.
vQ