在同一矩阵中有相应的列

时间:2012-06-30 15:41:48

标签: r loops

我正在用更快的应用函数替换所有循环。我有一个问题,使该功能依赖于前一列。

目前,我需要根据考试成绩分配成绩,这可以使用

data <- matrix(runif(100),20,5)
colnames(data) <- letters[1:5]
sapply(colnames(data),function(x){
  ifelse((data[,x] <= 0 & data[,x] < 0.50),'C',
         ifelse((data[,x] >= 0.50 & data[,x] < 0.70) ,'B','A'))})

但是,是否可以继续使用apply函数并扩展代码,以便无论返回“C”的列如何,该列右侧的所有后续成绩都将替换为该行中的“C”

万分感谢

R上。

3 个答案:

答案 0 :(得分:2)

首先,您当前的代码中不需要任何循环或ifelse;只需使用cut

as.character(cut(data,c(0,0.5,0.7,1),labels=c("C","B","A"),right=FALSE))->cdata
dim(data)->dim(cdata);cdata->data

你的第二个问题(在第一个“C”之后用“C”填充所有单元格)需要一个循环,可以像这样完成:

t(apply(data,1,function(x)
 ifelse(seq(along=x)<min(c(which(x=="C"),Inf)),x,"C"))
)

答案 1 :(得分:1)

请尝试使用ifelse,而不是使用嵌套的cut语句。它使事情更容易阅读。例如:

# Create data
data <- matrix(runif(100),20,5) 
# Assign a grade
x=apply(data, MARGIN=2, cut, breaks=c(0,0.5,0.7,1),labels=c('C','B','A'))

现在你制作重复的C函数,这有点棘手。

# Make the repeating C function.
find.c=function(x) 
    if ('C' %in% x) 
        c(
          x[seq(0,match('C',x)-1)], # Everything before the first C
          rep('C',length(x) - match('C',x) + 1) # After the first C
        )  
    else x
# Run it.
t(apply(x,MARGIN=1,find.c))

答案 2 :(得分:0)

data <- matrix(runif(100),20,5)
colnames(data) <- letters[1:5]
data.let <- sapply(colnames(data),function(x){
  ifelse((data[,x] <= 0 | data[,x] < 0.50),'C',
         ifelse((data[,x] >= 0.50 & data[,x] < 0.70) ,'B','A'))})
# Note the change of & to | above to make your sample data work

apply( data.let, 1, replaceCs )

其中`replaceCs是一个函数,它接受一个向量并用C替换C之后的任何内容。

一个这样的例子:

replaceCs <- function(x) {
   for(i in seq(2,length(x))) {
      if(x[i-1]=="C") x[i] <- "C"
   }
   x
}

可能会有更聪明的东西用rollapply炮制。