1

我正在用更快的应用功能替换所有循环。我在使函数依赖于上一列时遇到问题。

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

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。

4

3 回答 3

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"))
)
于 2012-06-30T16:54:19.283 回答
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))
于 2012-06-30T16:38:51.590 回答
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

于 2012-06-30T16:31:03.913 回答