Для поведения цикла в R - PullRequest
       11

Для поведения цикла в R

1 голос
/ 21 февраля 2012

Я пытаюсь использовать цикл for и оператор if в моем коде R, как показано ниже.

Он создает график плотности, а затем я пытаюсь добавитьвертикальная линия к плотности, которая окрашена по видам.

Когда я print(organism) в цикле for печатает столбец видов 4 раза, почему он не распечатывает его один раз?Так почему же он циклически повторяет мои данные 4 раза?

Коду удается добавить некоторые красные линии на график плотности, но почему он не добавляет оставшиеся цветные линии для других видов?

dat <- structure(list(pdb = structure(1:13, .Label = c("1akk.pdb", "1fi7.pdb", 
"1fi9.pdb", "1giw.pdb", "1hrc.pdb", "1i5t.pdb", "1j3s0.10.pdb", 
"1j3s0.11.pdb", "1j3s0.12.pdb", "1j3s0.13.pdb", "1j3s0.14.pdb", 
"2aiu.pdb", "2b4z.pdb"), class = "factor"), PA = c(1128, 1143, 
1119, 1130, 1055, 1112, 1120, 1121, 1135, 1102, 1121, 1037, 1179
), EHSS = c(1424, 1439, 1404, 1423, 1318, 1403, 1412, 1415, 1432, 
1391, 1413, 1299, 1441), Species = structure(c(2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 1L), .Label = c("BOSTAURUS", 
"EQUUSCABALLUS", "HOMOSAPIENS", "MUSMUSCULUS"), class = "factor")), .Names = c("pdb", 
"PA", "EHSS", "Species"), class = "data.frame", row.names = c(NA, 
-13L))

den.PA <- density(dat$PA)
plot(den.PA)

for (i in 1:length(dat)){
    lineat = dat$PA[i]
    organism = dat$Species[i]
    lineheight <- den.PA$y[which.min(abs(den.PA$x - lineat))]
    print (organism)
    if (organism == 'EQUUSCABALLUS'){
        col = 'red'
    }
    if (organism == 'HOMOSAPIENS'){
        col = 'blue'
    }
    if (organism == 'MUSMUSCULUS'){
        col = 'green'
    }
    if (organism == 'BOSTAURUS'){
        col = 'purple'
    }
    lines(c(lineat, lineat), c(0, lineheight), col = col)
}

Ответы [ 3 ]

2 голосов
/ 21 февраля 2012

Для более «R-ish» решения попробуйте использовать match, approx и points с типом гистограммы.

den.PA <- density(dat$PA)
cols <- data.frame(Species=c('EQUUSCABALLUS', 'HOMOSAPIENS', 'MUSMUSCULUS', 'BOSTAURUS'),
                   col=c('red', 'blue', 'green', 'purple'), stringsAsFactors=FALSE)
plot(den.PA)
points(approx(den.PA$x, den.PA$y, dat$PA), type="h", 
       col=cols$col[match(dat$Species, cols$Species)])
1 голос
/ 21 февраля 2012

Побочный ответ: вы получите более плавный код, если замените все if на одну switch конструкцию.

Со страницы справки:

 centre <- function(x, type) {
     + switch(type,
     +        mean = mean(x),
     +        median = median(x),
     +        trimmed = mean(x, trim = .1))
     + }

Одна из приятных вещей в том, что вы можете поместить столько, сколько хотите, в правую часть любого дела. например в примере, который я разместил, вы можете сделать:
+ mean = {cat"this is the mean"; y=mean(x)*sin(z);plot(z,y)}

как глупый пример.

1 голос
/ 21 февраля 2012

взяв dat из dput(), вы можете изменить код для перебора строк и сначала преобразовать PA в класс character перед извлечением элемента.Таким образом, вы получите 13 строк:

    den.PA <- density(dat$PA)
    plot(den.PA)

    for (i in 1:nrow(dat)){
        lineat <- dat$PA[i]
        organism <- as.character(dat$Species)[i]
        lineheight <- den.PA$y[which.min(abs(den.PA$x - lineat))]
        print (organism)
        if (organism == 'EQUUSCABALLUS'){
            col <- 'red'
        }
        if (organism == 'HOMOSAPIENS'){
            col <- 'blue'
        }
        if (organism == 'MUSMUSCULUS'){
            col <- 'green'
        }
        if (organism == 'BOSTAURUS'){
            col <- 'purple'
        }
        segments(lineat,0,lineat,lineheight,col=col)
    }

enter image description here

также я изменил lines() на segments(), так как у вас просто есть 2 балла.Это не имеет большого значения, однако.Я также изменил объявления, используя = на <-, что вредит большинству пользователей R меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...