请看一下这个简单的数据框:
1 4 a
2 5 b
3 6 c
4 7 d
5 8 e
6 9 f
7 10 g
暂时忽略第三列。我想创建一个带有二进制变量的第四列,该变量将指示特定行是前一行的延续。
让我举例说明,
1 4 a 1
2 5 b 0
3 6 c 0
4 7 d 1
5 8 e 0
6 9 f 0
7 10 g 1
第一行我们从"1 到 4"开始,这是我们的基础,路径的起点。 在下一行我们有"2 转到 5",但由于我们已经在 4,数字 2 不是延续,因此,第四列得到"0"。这一行与我们的基地不符。 在下一行"3 转到 6",再次断开连接,因为我们已经在 4,我们应该在 4 重新开始。
这正是接下来发生的事情..."4 转到 7"与第一行连接,因此第四列得到"1"。 同样,只有行"7 转到 10"重新连接路径并获得"1">
最终,我想过滤"1",因为字母列包含重要信息。但这很容易使用 dplyr。算了。
我失败的方法如下:我用 i 和 j 创建了一个循环,它将搜索第 2 列中的值何时等于第 1 列中的值。问题是例如,行"2 转到 5"也与行"5 转到 8"连接,并会收到"1">
我看不出如何指示循环何时找到第一个连接,"4 变为 7"使用该发现作为新基础。只有这样,下一个正回报才是以 7 开头的行。
我的头很痛。我希望头脑冷静的人能给我看光。
谢谢大家。
在 R 中使用简单循环的另一种尝试是:
x <- 1:7
y <- 4:10
largest_nr <- min(x, y) # to get a 1 in the first entry
res_vec <- c() # empty vector
# loop through the numbers and check if we have a new largest number
for (i in 1:length(x)) {
if (min(x[i], y[i]) >= largest_nr) {
# new largest number found
largest_nr <- max(x[i], y[i])
res_vec <- c(res_vec, 1)
} else {
# no new largest number found
res_vec <- c(res_vec, 0)
}
}
cbind(x, y, res_vec)
#> x y res_vec
#> [1,] 1 4 1
#> [2,] 2 5 0
#> [3,] 3 6 0
#> [4,] 4 7 1
#> [5,] 5 8 0
#> [6,] 6 9 0
#> [7,] 7 10 1
首先是数据集示例:
dat <-
structure(list(X = 1:7, Y = 4:10, Z = c("a", "b", "c", "d", "e",
"f", "g")), .Names = c("X", "Y", "Z"), class = "data.frame", row.names = c(NA,
-7L))
现在尝试以下操作。
next_one <- function(dat, curr){
# Get the connect point from the second column
i <- dat[curr, 2]
# Now a vector of potential continuations
i <- which(dat[, 1] >= i)
# If there's a continuation, it's the first,
# else we're at the end of the column
i <- if(length(i) >= 1) i[1] else 0L
i
}
W <- integer(nrow(dat))
W[1] <- 1L
curr <- 1
while(curr <= nrow(dat)){
i <- next_one(dat, curr)
if(i){
W[i] <- 1L
curr <- i
}else
break
}
new_dat <- cbind(dat, W)
new_dat
X Y Z W
1 1 4 a 1
2 2 5 b 0
3 3 6 c 0
4 4 7 d 1
5 5 8 e 0
6 6 9 f 0
7 7 10 g 1