我正在尝试编写一个函数,该函数将通过矩阵进行rowise处理并返回两个包含第一个和最后一个实例1的列号(x)的向量。但是,有一些条件。我的真实数据集是7,042行和841列。
使用下面的示例数据集
structure(list(T1 = c(NA, NA, NA, 1L, NA, NA, NA, NA, NA), T2 = c(NA,
NA, NA, 0L, NA, NA, NA, NA, NA), T3 = c(NA, 3L, 3L, 0L, 3L, NA,
NA, 3L, 3L), T4 = c(NA, 4L, NA, 0L, 0L, NA, 4L, 0L, 4L), T5 = c(5L,
5L, 5L, 0L, 0L, NA, 0L, 5L, 0L)), row.names = c(NA, -9L), class = "data.frame")
+----+----+----+----+----+
| T1 | T2 | T3 | T4 | T5 |
+----+----+----+----+----+
| NA | NA | NA | NA | 1 |
| NA | NA | 1 | 1 | 1 |
| NA | NA | 1 | NA | 1 |
| 1 | 0 | 0 | 0 | 0 |
| NA | NA | 1 | 0 | 0 |
| NA | NA | NA | NA | NA |
| NA | NA | NA | 1 | 0 |
| NA | NA | 1 | 0 | 1 |
| NA | NA | 1 | 1 | 0 |
+----+----+----+----+----+
向量1应该返回c(6,6,6,2,4,1,5,6,5)
,而向量2应该返回c(6,6,6,2,4,1,5,4,5)
我的第一次尝试是在下面,但这只会返回在每一列中找到1的最终位置
pattern <- matrix(data = NA, nrow = nrow(df), ncol = 1)
for (k in 1:ncol(df)) {
df[, k][df[, k] > 0] <- k
}
pattern[, 1] <- apply(df, 1, function(x) max(x, na.rm = TRUE)+1)
我的第二次尝试看起来像这样
extInd <- function(x) {
v1 <- max(which(x > 0)) + 1
v2 <- min(which(x > 0)) + 1
return(c(v1, v2))
}
apply(df, 1, extInd)
最大的问题是,我不确定如何检查出现的1是否仅由NA或0分隔,然后根据将它们分开的值来更改返回结果。
答案 0 :(得分:0)
我想与同事交谈后我可能已经解决了这个问题。我们可以在出现1的情况下返回最大列号+1,在最小列号0时返回。如果没有1,则返回1。如果没有零,则返回1的值。
structure(list(T1 = c(NA, NA, NA, 1L, NA, NA, NA, NA, NA), T2 = c(NA,
NA, NA, 0L, NA, NA, NA, NA, NA), T3 = c(NA, 3L, 3L, 0L, 3L, NA,
NA, 3L, 3L), T4 = c(NA, 4L, NA, 0L, 0L, NA, 4L, 0L, 4L), T5 = c(5L,
5L, 5L, 0L, 0L, NA, 0L, 5L, 0L)), row.names = c(NA, -9L), class = "data.frame")
extInd <- function(x) {
## check where 1 occurs and return max(x)+1
pos_1 <- max(which(x == 1), na.rm = TRUE) + 1
## if never, return 1
if (is.infinite(pos_1)) {
pos_1 <- 1
}
## check where 0 occurs and return first instance
pos_0 <- min(which(x == 0), na.rm = TRUE)
## if never 0, return pos_1
if (is.infinite(pos_0)) {
pos_0 <- pos_1
}
return(c(pos_1, pos_0))
}
suppressWarnings(t(apply(df, 1, extInd)))