我遇到嵌套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
中的color
与C2
中的物种匹配,则在新的向量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}}
感谢您的时间和帮助。
答案 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
将为您提供1
和9
,因为这两行{{1} })。
第二,当您发表声明Species == "Blue"
时,您没有为列abund[abund$Species == i, "C2"]:abund[abund$Species == i, "C4"]
C2
和C3
编制索引,而是从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])