R中按因子水平计算分位数

7

我有一个数据框,并且我正在尝试为数据框中的每个因子“strata”的水平创建一个新变量,其中包含连续变量var1的分位数。

# 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一样,它们在数据框中的顺序不正确。我们可以通过将分位数“箱”放入数据框中来检查这一点。

# 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]

“Aggregate”通常意味着返回一个比原始对象更小的对象。(在这种情况下,您将获得一个数据框,在其中x是每个分层的1个元素的list。)


(+1) for 3 different methods - ndoogan
@mnel 非常感谢!我知道我一定错过了什么简单的东西 - 我总是忘记 ave - Chris

1

使用ave函数对你的dat数据框进行操作。以下是使用你模拟的数据和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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接