Будучи cumsum
примитивом, вы можете увидеть здесь https://github.com/Microsoft/microsoft-r-open/blob/master/source/src/main/cum.c что R
он делает под капотом. Более того, если вы читаете из строки 215:
PROTECT(t = coerceVector(CAR(args), REALSXP));
n = XLENGTH(t);
PROTECT(s = allocVector(REALSXP, n));
setAttrib(s, R_NamesSymbol, getAttrib(t, R_NamesSymbol));
UNPROTECT(2);
Это делает принуждение от period
до numeric
и, поскольку структура периода, это только сохранение .Data
Сравнить
seconds_to_period(60)@.Data
seconds_to_period(59)@.Data
Следовательно, на уровне C, R не выполняет as.numeric
, но быстрее, более эффективно (но вы можете сказать менее тонко, потому что он не понимает другие элементы из .Data
, как это делает as.numeric
) приведения данных.
Смотри как это:
setClass("Foo", representation(.Data="numeric", number1 = "numeric", number2 = "numeric"))
bar <- new("Foo",.Data=5, number1 = 12, number2 = 31)
cumsum(bar)
Результат равен 5, потому что он только приводит к numeric
Data
Кроме того:
setClass("Foo2", representation(.Data="numeric", number1 = "numeric", number2 = "numeric"))
bar2 <- new("Foo2", number1 = 12, number2 = 31)
cumsum(bar2)
вернем вам numeric(0)
потому что нет .Data
И
setClass("Foo3", representation( number1 = "numeric", number2 = "numeric"))
bar3 <- new("Foo3", number1 = 12, number2 = 31)
cumsum(bar3)
Это вообще не работает: без .Data
, внутренне, R не знает, как привести его к numeric
при выполнении cumsum
Итак: это из-за того, как R
внутренне работает со сложными объектами S4.
Вы всегда можете указать lubridate
сотрудникам создать новый параметр seconds
и сохранить в .Data
совокупные секунды всего объекта S4. Я думаю, что таким образом cumsum
будет работать. Но сейчас они используют .Data
для хранения второго аргумента. См edit(seconds_to_period)
:
function (x)
{
span <- as.double(x)
remainder <- abs(span)
newper <- period(second = rep(0, length(x)))
slot(newper, "day") <- remainder%/%(3600 * 24)
remainder <- remainder%%(3600 * 24)
slot(newper, "hour") <- remainder%/%(3600)
remainder <- remainder%%(3600)
slot(newper, "minute") <- remainder%/%(60)
slot(newper, ".Data") <- remainder%%(60)
newper * sign(span)
}
Наконец, просто для удовольствия. Это моя пробная версия того, как заставить cumsum
работать здесь:
setClass("Period2",representation(.Data="numeric", period="Period"))
seconds_to_period_2 <- function(x){
(lapply(x, function(y) new("Period2", .Data=y, period=seconds_to_period(y))))
}
a<-seconds_to_period_2(1:60)
cumsum(a)
Лучший!