在R中剪切函数以考虑重复数据

时间:2014-08-20 14:53:25

标签: r

假设我有一系列数据表明年龄的个人年龄。这样

ages <- sample(40:80, 30, replace = F)

现在我想绘制(boxplot)另一个变量〜说重量

但是我希望将年龄样本切成以下catergories&lt; 50,&gt; 50,&gt; 60。大于70。 因此,66岁的个人体重将用于> 50和> 60的情节

我的理解是我使用cut命令

age.category <- cut(ages, breaks = c(40, 50, 60, 70, 80) ........)

但是,当我想要

时,如何格式化以重复数据
labels = c("x < 50", "x > 50", "x > 60", "x > 70")

1 个答案:

答案 0 :(得分:3)

这是一个替代的“multicut”函数,它允许您指定任意中断。这将重复值,每个组出现一次值。因此,如果您使用“64”,则会同时输出64, "x>50"64, "x>60"

#sample data
set.seed(15)
ages <- sample(40:80, 30, replace = F)
weights <- 100 + ages*.2 + rnorm(30, 0 , 20)

#custom breaks
#named list, names-categories, values = 2-vector with min/max
breaks<-list(
   "x<50" =c(-Inf, 50),
   "x>50" =c(50, Inf),
   "x>60" = c(60, Inf),
   "x>70" = c(70, Inf)
)

现在我们定义主辅助函数multicut

multicut <- function(x, breaks, vals=x, left.closed=TRUE, right.closed=FALSE, 
  x.name=if(missing(vals)) deparse(substitute(x)) else deparse(substitute(vals)),
  group.name="group") {

    unrowname <- function(x) {rownames(x)<-NULL; x}
    if (is.data.frame(vals)) {
        if(missing(x.name)) x.name<-names(vals)
        vals = Map(unrowname, split(vals, 1:nrow(vals)))
    }
    stopifnot(length(vals) == length(x))
    grp <- lapply(x, function(x) {
        mapply(function(z, br,l,r) {
            left<-if (l) z>=br[1] else z>br[1]
            right<-if (r) z<=br[2] else z<br[2]
            left & right
        }, x, breaks, left.closed, right.closed)
    })
    df <- do.call(rbind.data.frame, 
        Map(cbind.data.frame,  
        g=lapply(grp, function(z) if(any(z)) names(breaks)[z] else NA),
        x=vals))
    df[[1]] <- factor(df[[1]], levels=names(breaks))
    names(df) <- c(group.name, x.name)
    df
}

现在我们在样本数据上使用它

dd <- multicut(ages, breaks, weights)
boxplot(weights~group, dd)

multicut的三个重要参数是x,其中包含您希望进行分类的值,breaks,它是每个组的最小值/最大值的命名列表,以及可选vals,它是您要根据xbreaks进行拆分的矢量或数据框架。在这里,我们希望使用age来分割weights

enter image description here