1

我有以下数据框:

varnames<-c("ID", "a.1", "b.1", "c.1", "a.2", "b.2", "c.2")

a <-matrix (c(1,2,3,4, 5, 6, 7), 2,7)

colnames (a)<-varnames

df<-as.data.frame (a)


   ID  a.1  b.1  c.1  a.2  b.2  c.2
 1  1    3    5    7    2    4    6
 2  2    4    6    1    3    5    7

我想分别使用“a.1”、“b.1”和“c.1”的四分位数对“a.2”、“b.2”和“c.2”列进行分类:

cat.a.2<-cut(df$a.2, c(-Inf, quantile(df$a.1), Inf))#categorizing a.2 using quartiles of a.1

cat.a.2
[1] (-Inf,3] (-Inf,3]
Levels: (-Inf,3] (3,3.25] (3.25,3.5] (3.5,3.75] (3.75,4] (4, Inf]

cat.b.2<-cut(df$b.2, c(-Inf, quantile(df$b.1), Inf))# categorizing b.2 using quartiles of b.1

cat.b.2
[1] (-Inf,5] (-Inf,5]
Levels: (-Inf,5] (5,5.25] (5.25,5.5] (5.5,5.75] (5.75,6] (6, Inf]


cat.c.2<-cut(df$c.2, c(-Inf, quantile(df$c.1), Inf))# categorizing c.2 using quartiles of c.1

 cat.c.2
[1] (5.5,7] (5.5,7]
Levels: (-Inf,1] (1,2.5] (2.5,4] (4,5.5] (5.5,7] (7, Inf]

有没有办法自动完成这项任务?

我天真地试验了 sapply():

quant.vars<-c("a.1","b.1", "c.1") # creating a vector of the names of variables which quartiles I am going to use
vars<-c("a.2","b.2", "c.2") # creating a vector of the names of variables which I am going to categorize
sapply (vars,FUN=function (x){cut (df [,x], quantile (df[,quant.vars], na.rm=T))})
         a.2        b.2          c.2       
[1,] "(1,3.25]" "(3.25,4.5]" "(5.75,7]"
[2,] "(1,3.25]" "(4.5,5.75]" "(5.75,7]"

当然,这不是我想要的结果。

此外,当将“Inf”添加到 cut () 范围时,我看到以下错误:

sapply (vars,FUN=function (x){cut (df [,x], c(quantile (df[,quant.vars], Inf), na.rm=T))})

  Error in quantile.default(df[, quant.vars], Inf) : 'probs' outside [0,1]

总之,我的问题是如何制作 R:

  1. 计算后缀为 1 (a.1., b.1, c.1) 的变量的分位数

  2. 识别具有公共前缀的变量对(a.1 和 a.2、b.1 和 b.2、c.1 和 c.2)

  3. 在每一对中,使用分位数对具有后缀 2 的变量进行分类,从具有后缀 1 的变量中获得(a.2 按 a.1 分位数分类,b.2 按 b.1 分位数分类,c.2 按 c.2 分类。 1个分位数)

非常感谢

4

1 回答 1

3

像这样的东西?

#find duplicated letters
temp <- do.call(rbind,strsplit(names(df)[-1],".",fixed=TRUE))
dup.temp <- temp[duplicated(temp[,1]),]

#loop for cut
res <- lapply(dup.temp[,1],function(i) {
  breaks <- c(-Inf,quantile(a[,paste(i,1,sep=".")]),Inf)
  cut(a[,paste(i,2,sep=".")],breaks)
})

#make list a data.frame
res <- do.call(cbind.data.frame,res)
names(res) <- paste("cut",dup.temp[,1],2,sep=".")

#    cut.a.2  cut.b.2 cut.c.2
# 1 (-Inf,3] (-Inf,5] (5.5,7]
# 2 (-Inf,3] (-Inf,5] (5.5,7]

res[,1]
# [1] (-Inf,3] (-Inf,3]
# Levels: (-Inf,3] (3,3.25] (3.25,3.5] (3.5,3.75] (3.75,4] (4, Inf]

如果速度是一个问题,那么还有优化的空间。

于 2013-04-23T10:58:10.687 回答