首页 文章

R中因子水平的分位数

提问于
浏览
7

我有一个数据框,我正在尝试在数据框中创建一个新变量,该变量具有连续变量 var1 的分位数,对于每个级别的因子 strata .

# some data
set.seed(472)
dat <- data.frame(var1 = rnorm(50, 10, 3)^2,
                  strata = factor(sample(LETTERS[1:5], size = 50, replace = TRUE))
                  )

# function to get quantiles
qfun <- function(x, q = 5) {
    quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
        include.lowest = TRUE, labels = 1:q)
    quantile
}

我尝试使用两种方法,这两种方法都不会产生可用的结果 . 首先,我尝试使用 aggregateqfun 应用于 strata 的每个级别:

qdat <- with(dat, aggregate(var1, list(strata), FUN = qfun))

这将分数按系数级别返回,但输出很难强制回数据帧(例如,使用 unlist 不会将新变量值与数据帧中的正确行对齐) .

第二种方法是按步骤执行此操作:

tmp1 <- with(dat, split(var1, strata))
tmp2 <- lapply(tmp1, qfun)
tmp3 <- unlist(tmp2)
dat$quintiles <- tmp3

同样,这会为每个因子级别正确计算分位数,但很明显,与 aggregate 一样,它们在数据框中的顺序不正确 . 我们可以通过将分位数"bins"放入数据框来检查这一点 .

# get quantile bins
qfun2 <- function(x, q = 5) {
    quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
        include.lowest = TRUE)
    quantile
}

tmp11 <- with(dat, split(var1, strata))
tmp22 <- lapply(tmp11, qfun2)
tmp33 <- unlist(tmp22)
dat$quintiles2 <- tmp33

var1 的许多值都在 quantile2 的区间之外 . 我觉得我错过了一些简单的事情 . 任何建议将不胜感激 .

2 回答

  • 8

    我认为你的问题是你真的不想聚合,而是使用 ave ,(或 data.tableplyr

    qdat <- transform(dat, qq = ave(var1, strata, FUN = qfun))
    
    #using plyr
    library(plyr)
    
    qdat <- ddply(dat, .(strata), mutate, qq = qfun(var1))
    
    #using data.table (my preference)
    
    
    dat[, qq := qfun(var1), by = strata]
    

    聚合通常意味着返回一个小于原始对象的对象 . (在这种情况下,你得到一个data.frame,其中 x 是每个阶层1个元素的 list .

  • 1

    dat 数据框上使用 ave . 您的模拟数据和 qfun 函数的完整示例:

    # some data
    set.seed(472)
    dat <- data.frame(var1 = rnorm(50, 10, 3)^2,
                  strata = factor(sample(LETTERS[1:5], size = 50, replace = TRUE))
                  )
    
    # function to get quantiles
    qfun <- function(x, q = 5) {
        quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
            include.lowest = TRUE, labels = 1:q)
        quantile
    }
    

    而我的补充......

    dat$q <- ave(dat$var1,dat$strata,FUN=qfun)
    

相关问题