R中的For循环行为

R中的For循环行为,r,for-loop,R,For Loop,我试图在R代码中使用for循环和if语句,如下所示 它生成了一个密度图,然后我尝试在密度上添加一条垂直线,该线由物种着色 当我在for循环中打印生物体时,它会打印物种列4次,为什么不打印一次呢?因此,它是否在我的数据中循环4次 代码设法在密度图上添加了一些红线,但为什么不为其他物种添加剩余的彩色线呢 dat <- structure(list(pdb = structure(1:13, .Label = c("1akk.pdb", "1fi7.pdb", "1fi9.pdb", "1gi

我试图在R代码中使用for循环和if语句,如下所示

它生成了一个密度图,然后我尝试在密度上添加一条垂直线,该线由物种着色

当我在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)
}
从dput获取dat,您可以更改代码以迭代行,并在提取元素之前首先将PA转换为类字符。这样您将获得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)
    }
另外,我将直线更改为线段,因为您只有2个点。然而,这没有多大区别。我还使用=将声明更改为从dput获取dat,您可以将代码更改为迭代行,并在提取元素之前首先将PA转换为类字符。这样您将获得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)
    }

另外,我将直线更改为线段,因为您只有2个点。然而,这没有多大区别。我还使用=将声明更改为要获得更为R-ish的解决方案,请尝试使用match、approx和histogram类型的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)])

要获得更具R风格的解决方案,请尝试使用匹配、近似和直方图类型的点

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)])

旁白:如果用一个开关结构替换所有的if,代码会更平滑

从“帮助”页面:

 centre <- function(x, type) {
     + switch(type,
     +        mean = mean(x),
     +        median = median(x),
     +        trimmed = mean(x, trim = .1))
     + }
这里的一个好处是,你可以在任何箱子的右边放你想要的任何东西。e、 g.在我发布的示例中,您可以: +均值={catthis是均值;y=meanx*sinz;plotz,y}


举个愚蠢的例子。

侧面回答:如果用一个开关结构替换所有的if,代码会更平滑

从“帮助”页面:

 centre <- function(x, type) {
     + switch(type,
     +        mean = mean(x),
     +        median = median(x),
     +        trimmed = mean(x, trim = .1))
     + }
这里的一个好处是,你可以在任何箱子的右边放你想要的任何东西。e、 g.在我发布的示例中,您可以: +均值={catthis是均值;y=meanx*sinz;plotz,y}


举个愚蠢的例子。

您的read.table语句没有为我生成可用的对象。如果您有一个名为dat的看似正常的对象,那么您可以为我们复制并粘贴来自dputdat的控制台输出吗?dputdat输出在上面,您的循环只执行1:4,因为data.frame是一个列表,data.frame的长度是它的列数。您的read.table语句没有为我生成可用的对象。如果您有一个名为dat的看似正常的对象,那么您可以为我们复制并粘贴来自dputdat的控制台输出吗?dputdat输出在上面,您的循环只执行1:4,因为data.frame是一个列表,data.frame的长度是它的列数。同意,我试图用一堆嵌套的ifelse语句将它塞进一个对段的调用中,但放弃了+1对于R-nessagreed,我尝试使用一堆嵌套的ifelse语句将其塞进对段的单个调用中,但放弃了+1表示R-ness