r - Assign values by group when all that matters is the number of group members -
i recently ran following grouped operation: each group, values assigned evenly distributed numbers between -0.5 , 0.5, , if group has 1 element assigned value 0. instance, if had following observed groups:
g <- c("a", "a", "b", "b", "a", "c")
then expect assigned values:
outcome <- c(-0.5, 0, -0.5, 0.5, 0.5, 0)
the 3 observations in group assigned values -0.5, 0, , 0.5 (in order), 2 observations in group b assigned values -0.5 , 0.5 (in order), , 1 observation in group c assigned value 0.
normally when perform grouped operation on 1 vector vector, use ave
function, form ave(data.vector, group.vector, fun=function.to.apply.to.each.groups.data.vector.subset)
. in operation need know number of members in group, there no data.vector
. result, ended making data vector ignored in call ave
:
ave(rep(na, length(g)), g, fun=function(x) { if (length(x) == 1) { return(0) } else { return(seq(-0.5, 0.5, length=length(x))) } }) # [1] -0.5 0.0 -0.5 0.5 0.5 0.0
while gives me correct answer, it's pretty unsatisfying need make data vector ignore. there better way assign values group when matters number of elements in group?
from comments doesn't seem there's version of ave
takes group , function called number of elements in each group. suppose not particularly surprising since it's pretty specialized operation.
if had roll own version of ave
desired properties thin wrapper around ave
:
ave.len <- function(..., fun) { l <- list(...) do.call("ave", c(list(x=rep(na, length(l[[1]]))), l, fun=function(x) fun(length(x)))) } # original operation, using @akrun's 1-line command sequences g <- c("a", "a", "b", "b", "a", "c") ave.len(g, fun=function(n) seq(-0.5, 0.5, length=n)* (n!=1)+0l) # [1] -0.5 0.0 -0.5 0.5 0.5 0.0 # group of size n has n^th letter in alphabet ave.len(g, fun=function(n) rep(letters[n], n)) # [1] "c" "c" "b" "b" "c" "a" # multiple groups via ... argument (here everything's in own group) ave.len(g, 1:6, fun=function(n) rep(letters[n], n)) # [1] "a" "a" "a" "a" "a" "a"
Comments
Post a Comment