聚合中用户定义函数的问题
trouble with a user-defined function in aggregate
我正在尝试通过编写一个函数来插入聚合来摆脱 for 循环。进展不顺利。
样本数据为:
group <- c(1, 1, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2)
gdp <- c(3.5, 4.2, 5, 4, 4.2, 5, 5.5, 6, 3.5, 3.4, 4.0, 4.1, 4.3, 4.7)
df <- data.frame(group, gdp)
函数的目标是,对于一个组内的每个 x (gdp) 值,找出 x 与 x 的最小值之间的绝对差值,以及 x 与最大值之间的差值x 的值和 return 中较小的一个。如果一组中只有 1 个值,或者该值是组中的第一项或最后一项,则差值为 0,在这种情况下 return 0.
顺序很重要,因为我不希望它整理所有第 1 组;我希望将函数应用于一组中的每个 gdp 值,然后转到下一组。
函数为:
get_dist <- function(x){
a <- abs(x - min(x))
b <- abs(x -max(x))
c <- ifelse(a < b, a, ifelse(a = 0), 0, b)
return(c)
}
然后是最后一步,使用聚合:
edge_dist <- with(df, aggregate(group, list(gdp), get_dist))
对我哪里出错有什么建议吗?这不是我所希望的return。
使用 data.table 而不是聚合:
library(data.table)
# step 1: assign unique groups
u_grps <- rle(df$group)$lengths
df$id <- rep(1:length(u_grps), u_grps)
# step 2: calculate your row-level stuff using data.table
data.table(df)[, min_abs_diff:=pmin(abs(gdp-max(gdp)), abs(gdp-min(gdp))),
by=id][]
# result:
# group gdp id min_abs_diff
# 1: 1 3.5 1 0.0
# 2: 1 4.2 1 0.7
# 3: 1 5.0 1 0.0
# 4: 2 4.0 2 0.0
# 5: 2 4.2 2 0.2
# 6: 2 5.0 2 1.0
# 7: 2 5.5 2 0.5
# 8: 2 6.0 2 0.0
# 9: 3 3.5 3 0.0
# 10: 1 3.4 4 0.0
# 11: 1 4.0 4 0.1
# 12: 1 4.1 4 0.0
# 13: 2 4.3 5 0.0
# 14: 2 4.7 5 0.0
注意:此示例仅打印输出。如果你想存储在一个对象中,使用类似
df2 <-
data.table(df)[, min_abs_diff:=pmin(abs(gdp-max(gdp)), abs(gdp-min(gdp))),
by=id]
我正在尝试通过编写一个函数来插入聚合来摆脱 for 循环。进展不顺利。
样本数据为:
group <- c(1, 1, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2)
gdp <- c(3.5, 4.2, 5, 4, 4.2, 5, 5.5, 6, 3.5, 3.4, 4.0, 4.1, 4.3, 4.7)
df <- data.frame(group, gdp)
函数的目标是,对于一个组内的每个 x (gdp) 值,找出 x 与 x 的最小值之间的绝对差值,以及 x 与最大值之间的差值x 的值和 return 中较小的一个。如果一组中只有 1 个值,或者该值是组中的第一项或最后一项,则差值为 0,在这种情况下 return 0.
顺序很重要,因为我不希望它整理所有第 1 组;我希望将函数应用于一组中的每个 gdp 值,然后转到下一组。
函数为:
get_dist <- function(x){
a <- abs(x - min(x))
b <- abs(x -max(x))
c <- ifelse(a < b, a, ifelse(a = 0), 0, b)
return(c)
}
然后是最后一步,使用聚合:
edge_dist <- with(df, aggregate(group, list(gdp), get_dist))
对我哪里出错有什么建议吗?这不是我所希望的return。
使用 data.table 而不是聚合:
library(data.table)
# step 1: assign unique groups
u_grps <- rle(df$group)$lengths
df$id <- rep(1:length(u_grps), u_grps)
# step 2: calculate your row-level stuff using data.table
data.table(df)[, min_abs_diff:=pmin(abs(gdp-max(gdp)), abs(gdp-min(gdp))),
by=id][]
# result:
# group gdp id min_abs_diff
# 1: 1 3.5 1 0.0
# 2: 1 4.2 1 0.7
# 3: 1 5.0 1 0.0
# 4: 2 4.0 2 0.0
# 5: 2 4.2 2 0.2
# 6: 2 5.0 2 1.0
# 7: 2 5.5 2 0.5
# 8: 2 6.0 2 0.0
# 9: 3 3.5 3 0.0
# 10: 1 3.4 4 0.0
# 11: 1 4.0 4 0.1
# 12: 1 4.1 4 0.0
# 13: 2 4.3 5 0.0
# 14: 2 4.7 5 0.0
注意:此示例仅打印输出。如果你想存储在一个对象中,使用类似
df2 <-
data.table(df)[, min_abs_diff:=pmin(abs(gdp-max(gdp)), abs(gdp-min(gdp))),
by=id]