我有一个数据框,我试图在数据框中创建一个新变量,该变量具有连续变量的分位数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
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用两种方法,这两种方法都不会产生可用的结果.首先,我尝试使用aggregate适用qfun于以下各级strata:
qdat <- with(dat, aggregate(var1, list(strata), FUN = qfun))
Run Code Online (Sandbox Code Playgroud)
这通过因子级别返回分位数,但是输出很难强制回到数据帧中(例如,使用unlist不将新变量值与数据帧中的正确行对齐).
第二种方法是按步骤执行此操作:
tmp1 <- with(dat, split(var1, strata))
tmp2 <- lapply(tmp1, qfun)
tmp3 <- unlist(tmp2)
dat$quintiles <- tmp3
Run Code Online (Sandbox Code Playgroud)
同样,这会为每个因子级别正确计算分位数,但很明显,因为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
Run Code Online (Sandbox Code Playgroud)
许多价值观var1都在quantile2.我觉得我错过了一些简单的事情.任何建议将不胜感激.
我认为你的问题是你真的不想聚合,而是使用ave,(data.table或者plyr)
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]
Run Code Online (Sandbox Code Playgroud)
聚合通常意味着返回一个小于原始对象的对象.(在这种情况下,你得到的data.frame x是list每个层次的1个元素.