select 如何根据 R 中特定范围的位置删除行

How select and remove rows based on position for a specific range in R

假设我有两个这样的数据框:

df1 <- data.frame(a = c(1,2,4,0,0),
             b = c(0,3,5,5,0),
             c = c(0,0,6,7,6))

df2 <- data.frame(a = c(3,6,8,0,0),
             b = c(0,9,10,4,0),
             c = c(0,0,1,4,9))

然后我联合起来,喜欢

df3 <- full_join(df1, df2)
print(df3)

   a  b c
1  1  0 0
2  2  3 0
3  4  5 6
4  0  5 7
5  0  0 6
6  3  0 0
7  6  9 0
8  8 10 1
9  0  4 4
10 0  0 9

请注意,我一直使用相同的模式,第 1 行和第 2 行中有零;在第 9 行和第 10 行。我在第 4 行和第 7 行之间也有零。 我只想删除第 4 行和第 7 行之间的零。 所以,我可以解决它,比如:

df3[4,1] <- NA
df3[5,1] <- NA
df3[5,2] <- NA
df3[6,2] <- NA
df3[6,3] <- NA
df3[7,3] <- NA

new.df3 <-  as.data.frame(lapply(df3, na.omit))
print(new.df3)

  a  b c
1 1  0 0
2 2  3 0
3 4  5 6
4 3  5 7
5 6  9 6
6 8 10 1
7 0  4 4
8 0  0 9

但是不够优雅,非常耗时。 有什么想法吗?非常感谢,提前致谢。 最好!

首先,您找出第 4 行和第 7 行之间的哪一个为零。

to_remove <- apply(df3[4:7, ], 1, function(x) which(x == 0))

然后,你用 NA 代替它们。

for(i in seq(length(to_remove))){
  df3[as.numeric(names(to_remove))[i], to_remove[[i]]] <- NA
}

最后,放下它们。

new.df3 <-  as.data.frame(lapply(df3, na.omit))
print(new.df3)

这里有一个不同的方法:

mask <- !(seq(nrow(df3)) %in% 4:7 & df3 == 0)
df.lst <- lapply(1:3, function(x) df3[mask[, x], x])
sapply(df.lst, length)
# [1] 8 8 8  # Check to make sure the columns are the same length
names(df.lst) <- colnames(df3)
(new.df3 <- as.data.frame(df.lst))
#   a  b c
# 1 1  0 0
# 2 2  3 0
# 3 4  5 6
# 4 3  5 7
# 5 6  9 6
# 6 8 10 1
# 7 0  4 4
# 8 0  0 9
df3 %>%
  mutate(rn = between(row_number(), 4, 7)) %>%
  summarise(across(-rn, ~.x[!(.x == 0 & rn)]))
  a  b c
1 1  0 0
2 2  3 0
3 4  5 6
4 3  5 7
5 6  9 6
6 8 10 1
7 0  4 4
8 0  0 9