我想将此自定义功能与aggregate
一起使用:
#linear regression f-n
CalculateLinRegrDiff = function (sample){
fit <- lm(value~ date, data = sample)
diff(range(fit$fitted))
}
dataset2 = aggregate(value ~ id + col, dataset, CalculateLinRegrDiff(dataset))
我收到错误:
Error in get(as.character(FUN), mode = "function", envir = envir) :
object 'FUN' of mode 'function' was not found
怎么了?
答案 0 :(得分:1)
首先,您使用aggregate
的语法是错误的。将函数CalculateLinRegrDiff
传递给CalculateLinRegrDiff(dataset)
参数,而不是一个求值的FUN
。
第二,您选择了错误的工具。 aggregate
无法帮助您按组拟合回归。它根据RHS上的组合在~
的LHS上分割向量,然后在LHS上应用FUN
。也就是说,FUN
应该是适用于原子向量而不是数据帧的函数。假设mean
,sd
,quantile
等都是以原子向量为输入的函数。 CalculateLinRegrDiff
需要输入数据框,并且无法与aggregate
一起使用。
请注意,有时我们会在LHS上使用cbind
,例如cbind(x, y) ~ f
。这意味着我们将FUN
与x ~ f
和y ~ f
并行应用。 LHS变量是独立的,不能一起使用。
最合适的工具是by
函数。它将数据帧拆分为子数据帧,并在每个子帧上应用FUN
。因此非常适合按组回归。
by(dataset[c("value", "date")], dataset[c("id", "col")], CalculateLinRegrDiff)
一个简单的可复制示例:
set.seed(0)
dataset <- data.frame(value = runif(20), date = runif(20),
f = sample(gl(2, 10)), g = sample(gl(4, 5)))
oo <- by(dataset[c("value", "date")], dataset[c("f", "g")], CalculateLinRegrDiff)
str(oo)
# by [1:2, 1:4] 0.307 0.251 0.109 0.201 0.472 ...
# - attr(*, "dimnames")=List of 2
# ..$ f: chr [1:2] "1" "2"
# ..$ g: chr [1:4] "1" "2" "3" "4"
由于CalculateLinRegrDiff
是一个返回单个标量的标量函数,因此by
会将结果oo
简化为数组而不是列表。该数组就像一个列联表,因此我们可以使用as.data.frame
的“表”方法将其重塑为数据框:
oo <- as.data.frame.table(oo)
# f g Freq
#1 1 1 0.3069877
#2 2 1 0.2508591
#3 1 2 0.1087895
#4 2 2 0.2007295
#5 1 3 0.4715680
#6 2 3 0.4942069
#7 1 4 0.3223174
#8 2 4 0.4687340
名称“ Freq”可能是不需要的,但您可以轻松更改它。说names(oo)[3] <- "foo"
。
正如我在关于您的问题的评论中所说,我们也可以使用split
和lapply
。但是,没有简单的方法可以将结果转换为漂亮的数据框。
datlist <- split(dataset[c("value", "date")], dataset[c("f", "g")], drop = TRUE)
rr <- lapply(datlist, CalculateLinRegrDiff)
stack(rr)
# values ind
#1 0.3069877 1.1
#2 0.2508591 2.1
#3 0.1087895 1.2
#4 0.2007295 2.2
#5 0.4715680 1.3
#6 0.4942069 2.3
#7 0.3223174 1.4
#8 0.4687340 2.4
我建议您阅读Linear Regression and group by in R,以获得有关按组回归的详尽演示。