【问题标题】:Have sapply depend on column in same matrixsapply 依赖于同一矩阵中的列
【发布时间】:2012-06-30 15:41:47
【问题描述】:

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

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

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.

【问题讨论】:

  • apply 系列命令并不总是更快。此外,如果您更好地描述您想要什么,我们可能会提供帮助。请告诉我们您的意图,而不仅仅是转储一些我们必须解析的代码(这可能是也可能不是您真正想要的!)
  • 抱歉,我正在为我的设施中的大学生汇总成绩。我需要拿数字成绩并将它们转换为字母,分数在 40-50 = D、50-60 = C 之间,依此类推。上面的代码可以解决这个问题。对于课程的持续评估部分,如果学生低于某个成绩,学生将需要重复 - 无论后续的 CA 成绩如何。我目前在一个循环中执行此操作,这可行,但我认为使用 apply 函数可能会更干净、更快捷。谢谢你的帮助,R。

标签: r loops


【解决方案1】:

首先,您当前的代码中不需要任何循环或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"))
)

【讨论】:

  • 很好地使用ifelse来替换Cs。
【解决方案2】:

不要使用嵌套的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))

【讨论】:

  • 很好地使用match 来避免循环。
【解决方案3】:
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 可能会制造出更聪明的东西。

【讨论】:

    猜你喜欢
    • 2018-02-03
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多