将数据框与If语句和循环相关联

时间:2017-01-25 22:23:19

标签: r loops if-statement for-loop

我有以下数据框:

df1 <- data.frame(ProjectID=c(10,11,12,13),
              Value1=c(101.25,102.85,102.95,103.15),
              Value2=c(103.58,104.27,104.68,106.01))
df2 <- data.frame(ProjectID=c(10,10,11,11,11,12,13,13),
              Value3=c(98.32,102.58,99.66,103.47,105.63,105.18,102.02,104.98))

我想创建以下列df1$Value4,如果满足以下条件,则会从df2$Value3拉出来:

  1. ProjectIDs必须与df1&amp; df2
  2. df2$Value3必须介于df1$Value1&amp; df1$Value2
  3. 如果不满足上述2个条件,请输入“”
  4. 我对使用循环和if语句感兴趣,如果可能的话。非常感谢任何帮助。

    输出应如下所示:

    df1 <- data.frame(ProjectID=c(10,11,12,13),
                  Value1=c(101.25,102.85,102.95,103.15),
                  Value2=c(103.58,104.27,104.68,106.01),
                  Value4=c(102.58,103.47,"",104.98))
    

2 个答案:

答案 0 :(得分:1)

这将merge两个data.frame,然后删除Value3不在Value1和Value2之间的行。第二个merge将添加df1中不满足先前条件的行。最后,最后一个命令将重命名该列。

df3 <- merge(df1, df2)
df3 <- df3[df3$Value1 < df3$Value3 & df3$Value3 < df3$Value2, ]
df3 <- merge(df1, df3, all.x = TRUE)
colnames(df3)[colnames(df3) == "Value3"] <- "Value4"

df3
  ProjectID Value1 Value2 Value4
1        10 101.25 103.58 102.58
2        11 102.85 104.27 103.47
3        12 102.95 104.68     NA
4        13 103.15 106.01 104.98

答案 1 :(得分:0)

通过循环和逻辑语句来完成它会使代码有点长。我确信dplyr声明可以缩短它。另外,我不确定您打算如何处理输出,但是R会将Value4字段转换为字符数据类型,因为“”。如果您希望之后进行任何类型的数据操作,我建议使用NA而不是“”。为此,只需在下面的代码中用“NA”替换“”。无论如何,您正在寻找的代码是:

df1$Value4 <- ""

for (i in 1:nrow(df1)) {
  match_df2 <- df2$Value3[df2$ProjectID == df1$ProjectID[i]]

  btwn <- c(df1$Value1[i], df1$Value2[i])
  btwn <- sort(btwn)
  match_v12 <- c()
  for (j in 1:length(match_df2)) {
    if (match_df2[j] >= btwn[1] & match_df2[j] <= btwn[2]) {
      match_v12 <- rbind(match_v12, match_df2[j])
    }
  }
  if (length(match_v12) == 0) {
    df1$Value4[i] <- ""
  } else {
    df1$Value4[i] <- max(match_v12)
  }
}

首先在df1中创建空的Value4字段,并用空字符串填充它。第一个循环语句将循环遍历df1中的每个projectID,并确定df2​​中ProjectID的匹配位置。那些匹配的位置存储在match_df2中。接下来,将Value1和Value2放入一个名为btwn的向量中以允许排序。在您给出的示例中,Value1始终小于Value2,但我不确定是否总是如此。

下一个for循环检查以查看匹配的Value3值是否在Value1和Value2之间。如果Value3介于两者之间,则会将Value3添加到名为match_v12的向量中。如果为单个ProjectID找到多个匹配项,则我假定匹配的Value3s的最大值。您可以将此更改为您喜欢的任何内容,我只是放下了一些东西。最后,如果找不到匹配项,则生成“”(最后一部分是冗余的,但总的来说,不是错误的代码)。

希望这有帮助