【问题标题】:For loop with conditional if statements带有条件 if 语句的 For 循环
【发布时间】:2017-11-16 01:59:11
【问题描述】:

我无法弄清楚这段代码有什么问题。我有一个名为 Fish 的数据框。我想添加一个名为 CombineMe 的列,默认值为 0。如果它满足两个条件(数据源 = A 和示例方法 = 视觉那么它将等于 501 并且如果数据源 = B,则该值将更改为 501 & 分类单元代码是三个 EJ、EL 或 RV)。我无法完全弄清楚我哪里出错了。我已经尝试调整 [i] 的位置并添加逗号...

for(i in 1:length(Fish)) {
Fish$CombineMe <- 0 
if (Fish$data_source == "A" & Fish$sample_method == "visual") {
  Fish$CombineMe [i] <- 501
} else if (Fish$data_source == "B" & Fish$taxon_name == c("EJ", "EL", "RV")){
  Fish$CombineMe [i] <- 501
}}

下面是 Fish 的简明示例:

Fish <- data.frame ("data_source"=c("A", "A", "B", "C", "C", "D", "D"), "sample_method"= c("visualfish", "fish", "fish", "fish", "fish", "fish", "fish"), 
                  "taxon_name"=c("EJ", "EJ", "RV", "EJ", "RV", "EL", "HR"))

【问题讨论】:

  • 尝试使用 Fish 列的 1 而不是整个数据框本身。 length(Fish$column)。或使用1:nrow(Fish)
  • 刚刚尝试过,得到了相同的结果。我得到了 CombineMe 列,但它只有 0,它没有填写任何 501。这是我得到的警告 if (Fish$data_source == "sni" & Fish$taxon_name == ... : 条件有长度> 1 并且只使用第一个元素
  • @AllyD 你能显示一些数据吗?
  • FIsh$Combine &lt;- ifelse(Fish$data_source == "A" &amp; Fish$sample_method == "visual", 501, ifelse(Fish$data_source == "B" &amp; Fish$taxon_name == c("EJ", "EL", "RV"), 501, 0))
  • 第一件事,Fish$CombineMe &lt;- 0 应该不在循环中。第二件事,使用i 索引进行比较。例如,Fish$data_source[i] == "A" &amp; Fish$sample_method[i] == "visual"。第三件事将你的第二个if 语句更改为Fish$taxon_name[i] %in% c("EJ", "EL", "RV"),最后但并非最不重要的是,如果你可以显示reproducible example,那么肯定有更好的方法来做到这一点。

标签: r for-loop if-statement


【解决方案1】:

这是有问题的代码行:

Fish$CombineMe <- 0

对于循环的每次迭代,您都将整列清零。将它移到循环之外和之前,它应该可以工作。

但是 R 是一种矢量化语言,一个更好的赋值方式甚至根本不用循环:

cond1 <- Fish$data_source == 'A' & Fish$sample_method == 'visual'
cond2 <- Fish$data_source == "B" & Fish$taxon_name %in% c('EJ', 'EL', 'RV')
Fish$CombineMe <- ifelse(cond1 | cond2, 501, 0)

【讨论】:

  • 非常感谢,效果很好!首先,我绝对没有意识到我只是把它归零。我喜欢更简化的 ifelse。我对 R 非常陌生,所以每天都在学习新东西!
【解决方案2】:

通常您需要提供 Fish 数据框的外观。我尝试根据您给定的代码猜测:

Fish$CombineMe <- 0 
for(i in 1:nrow(Fish)) {

if (Fish$data_source[i] == "A" & Fish$sample_method[i] == "visual") {
  Fish$CombineMe[i] <- 501
} else if (Fish$data_source[i] == "B" & Fish$taxon_name[i] %in% c("EJ", "EL", "RV")){
  Fish$CombineMe [i] <- 501
}}

不过,我认为您不需要循环。这是使用 ifelse 的替代方法。

Fish$CombineMe <- 0
Fish$CombineMe <- ifelse(Fish$data_source == "A" & Fish$sample_method == "visual", 501, Fish$CombineMe)
Fish$CombineMe <- ifelse(Fish$data_source == "B" & Fish$taxon_name %in% c("EJ", "EL", "RV"), 501, Fish$CombineMe)

【讨论】:

    【解决方案3】:

    您遇到的问题是因为每次循环时都定义了Fish$CombineMe &lt;- 0,所以每次都将孔列重置为cero。要解决这个问题:

    Fish$CombineMe[i] <- 0 
    

    【讨论】:

      猜你喜欢
      • 2022-11-26
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多