与dataframes if语句和循环
我有以下dataframes:与dataframes 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))
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
拉,如果满足以下条件:
ProjectIDs
必须匹配df1
&df2
df2$Value3
必须在之间&df1$Value2
- 如果上述两个条件不具备,输入“”
我很感兴趣,使用循环和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))
回答:
由循环和逻辑语句做它使代码有点长。我确信dplyr声明可以缩短这一点。另外,我不确定你计划如何处理输出,但是由于“”,R会将Value4字段转换为字符数据类型。如果您希望事后进行任何类型的数据操作,我会建议使用NAs而不是“”。要做到这一点,只需在下面的代码中用“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创建空值4场和一个空字符串填充它。第一个循环语句将遍历df1中的每个projectID并确定df2中的ProjectIDs的匹配位置。这些匹配位置存储在match_df2中。接下来,将Value1和Value2放入一个名为btwn的向量中,以便进行排序。在你给出的例子中,Value1总是小于Value2,但我不确定这是否总是如此。
next for循环检查是否匹配的Value3值在Value1和Value2之间。如果Value3介于两者之间,则会将Value3添加到称为match_v12的矢量。如果为单个ProjectID找到多个匹配项,那么我会假定匹配的Value3的最大值。你可以把它改成你喜欢的任何东西,我只是放下一些东西。最后,如果找不到匹配,则产生“”(这最后一部分是冗余的,但总体而言,不是错误的代码)。
希望这有助于
回答:
这将merge
两个data.frame
,然后取出其中值3并不值1和值2之间的行。第二个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
以上是 与dataframes if语句和循环 的全部内容, 来源链接: utcz.com/qa/261332.html