R for循环创建一个永远的类变量

时间:2013-06-11 11:46:32

标签: performance r if-statement for-loop

我的问题包括两部分。我有一个带有ID的矩阵和几个从0到180的值的列(代表时间)。我想用子组总结这些,然后在各列之间进行比较。例如,有多少ID从第5列的0-10切换到第6列的11+

现在,我的第一个想法是SAS风格的格式命令。这将让我将整数分组为不同的块(0-10,11-20,21-30等)。但是,似乎这不存在。

我的解决方案是循环遍历此矩阵的所有值(双循环)并检查值是否落在某些范围(if语句的字符串)之间,然后将此值输入到一个仅跟踪类的新矩阵中。例如:

# search through columns
for (j in 2:(dim(Tab2)[2])){ 
    # search through lines
    for (i in 1:dim(Tab2)[1]){ 
        if (is.na(Tab2[i,j])){
            tempGliss[i,j] <- "NA"}
        else if (Tab2[i,j]==0){
            tempGliss[i,j] <- "Zero"}
        else if (Tab2[i,j]>0 & Tab2[i,j]<=7){
            tempGliss[i,j] <- "1-7"}
        else if (Tab2[i,j]>=7 & Tab2[i,j]<=14){
            tempGliss[i,j] <- "7-14"}
        else if (Tab2[i,j]>=15 & Tab2[i,j]<=30){
            tempGliss[i,j] <- "15-30"}
        else if (Tab2[i,j]>=31 & Tab2[i,j]<=60){
            tempGliss[i,j] <- "31-60"}
        else if (Tab2[i,j]>=61 & Tab2[i,j]<=90){
            tempGliss[i,j] <- "61-90"}
        else if (Tab2[i,j]>=91 & Tab2[i,j]<=120){
            tempGliss[i,j] <- "91-120"}
        else if (Tab2[i,j]>=121 & Tab2[i,j]<=150){
            tempGliss[i,j] <- "121-150"}
        else if (Tab2[i,j]>=151 & Tab2[i,j]<=180){
            tempGliss[i,j] <- "151-180"}
        else if (Tab2[i,j]>180){
            tempGliss[i,j] <- ">180"}
    }
}

这里Tab2是我的原始矩阵,而tempGliss就是我作为一个类创建的。这需要非常长的时间!我的文件非常大,这无济于事。有什么方法可以加快速度吗? for循环或if语句的替代方案?

1 个答案:

答案 0 :(得分:1)

也许您可以使用cut

Tab2 <- data.frame(a = 1:9, b = c(0, 7, 14, 30, 60, 90, 120, 150, 155)
        ,c = c(0, 1, 7, 15, 31, 61, 91, 121, 155))
repla <- c("Zero", "1-7", "7-14", "15-30", "31-60", "61-90", "91-120", "121-150", "151-180", ">180")

for(j in 2:(dim(Tab2)[2])){
 dum <- cut(Tab2[,j], c(-Inf,0,7,14,30,60,90,120,150,180, Inf))
 levels(dum) <- repla
 Tab2[,j] <- dum
}

> Tab2
  a       b       c
1 1    Zero    Zero
2 2     1-7     1-7
3 3    7-14     1-7
4 4   15-30   15-30
5 5   31-60   31-60
6 6   61-90   61-90
7 7  91-120  91-120
8 8 121-150 121-150
9 9 151-180 151-180

我没有仔细看过它,但你可能需要稍微调整一下。