r - 如何使用for循环和ifelse创建向量

时间:2016-08-17 22:03:56

标签: r if-statement for-loop

我遇到嵌套for循环和ifelse语句的问题。这是我的数据框 Species Total C1 C2 C3 C4 1 Blue 223 73 30 70 50 2 Black 221 17 50 56 98 3 Yellow 227 29 99 74 25 4 Green 236 41 97 68 30 5 Red 224 82 55 21 66 6 Orange 284 69 48 73 94 7 Black 154 9 63 20 62 8 Red 171 70 58 13 30 9 Blue 177 57 27 8 85 10 Orange 197 88 61 18 30 11 Orange 112 60 8 31 13

abund

我想将colors列中的一些列加在一起,但前提是它们与我在向量colors <- c("Black", "Red", "Blue") 中指定的正确种类相匹配。

Species

因此,如果abund中的colorC2中的物种匹配,则在新的向量C4中将minus列添加到abund }。如果color中的物种与minus中的物种不匹配,则将0添加到新的矢量# Use for loop to create vector of sums for select species or 0 for species not selected for( i in abund$Species) { for( j in colors) { minus <- ifelse(i == j, sum(abund[abund$Species == i, "C2"]:abund[abund$Species == i, "C4"]), 0) } }

我的代码出现问题并希望它只是定义范围的一个小问题,但我不确定。到目前为止,这是我的代码:

There were 12 warnings (use warnings() to see them)

返回此内容:minus 这个&#34;矢量&#34;:[1] 0 minus [1] 150 204 0 0 142 0 145 101 120 0 0

这是我的目标:

{{1}}

感谢您的时间和帮助。

3 个答案:

答案 0 :(得分:3)

这可能更好,没有任何循环。

# Create the vector
minus <- rep(0, nrow(abund))
# Identify the "colors" cases
inColors <- abund[["Species"]] %in% colors
# Set the values
minus[inColors] <- rowSums(abund[inColors, c("C2","C3","C4")])

此外,对于它的价值,原始代码存在很多问题。首先,您的第一个for循环没有按照您的想法进行。在每一轮中,i的值被设置为abund$Species中的下一个值,因此首先是Blue然后是Black,然后是Yellow等。因此,您使用abund[abund$Species == i, ]进行索引,可能会返回多行(例如Blue将为您提供19,因为这两行{{1} })。

第二,当您发表声明Species == "Blue"时,您没有为列abund[abund$Species == i, "C2"]:abund[abund$Species == i, "C4"] C2C3编制索引,而是从C4中的值开始生成序列并以C2中的值结束。例如,当C4返回i == "Yellow"或99,98,97,...,26,25时。您收到这些警告的原因是此问题与最后一个问题的组合。例如,当99:25时,你试图从30和27开始并在50和85结束时发出一个序列。警告说它只是在开始和结束时使用第一个数字并给出你i == "Blue"

最后,你不断写出30:50的价值,而不是添加它。您需要首先创建上面的减号并为其分配索引,例如minus

答案 1 :(得分:2)

请注意,ifelse是矢量化的,因此您在使用时通常不要需要任何for循环。

我最喜欢Barker的答案,但如果你想用ifelse做这个,那就是这样:

abund$minus = with(abund, ifelse(
    Species %in% colors,  # if the species matches
    C2 + C3 + C4,         # add the columns
    0                     # otherwise 0
))

即使这只是一行而Barker是3,但对于大数据,避免ifelse会稍微有效。

但是,ifelse语句可以嵌套,并且在条件变得复杂时通常更容易使用 - 所以肯定有使用它们的好时机。对于中小型数据,速度差异可以忽略不计,因此只需使用您认为的第一个。

答案 2 :(得分:-1)

# Create a column called minus with the length of the number of existing rows. 

# The default value is zero.

abund$minus <- integer(nrow(abund))

# Perform sum of C2 to C4 only in those rows where Species is in the colors vector

abund$minus[abund$Species %in% colors] <- rowSums(abund[abund$Species %in% colors,5:7])