首页 > 解决方案 > 是否有任何函数可以从 R 中的数据框中提取几行(不连续)?

问题描述

我正在尝试从数据框中提取几行(不是一个接一个)。应删除的行范围在另一个数据框中。

我试图用 for 循环提取行,但不幸的是只删除了最后一个范围。

这是我使用的代码行(在'for'循环内,而'i'是变量):

new_df <- main_df[-(erase_df$starts[i]:erase_df$stops[i]),]

例如:这是我要更改的数据框(main_df)

> main_df
   v1  v2     v3
1   1 bla blabla
2   2 bla blabla
3   3 bla blabla
4   4 bla blabla
5   5 bla blabla
6   6 bla blabla
7   7 bla blabla
8   8 bla blabla
9   9 bla blabla
10 10 bla blabla
11 11 bla blabla
12 12 bla blabla
13 13 bla blabla
14 14 bla blabla
15 15 bla blabla

这是包含我要删除的行范围的数据框(erase_df)(“starts”向量表示应删除第一个行范围,“stops”向量表示应删除该范围内的最后一行)

> erase_df
  starts stops
1      3     5
2      9    10
3     12    14

所以新的数据框应该是这样的:

> new_df
   v1  v2     v3
1   1 bla blabla
2   2 bla blabla
6   6 bla blabla
7   7 bla blabla
8   8 bla blabla
11 11 bla blabla
15 15 bla blabla

我希望输出看起来像我上面提到的 (new_df) ,但不是它,而是删除了 erase_df 的最后一个范围(开始 = 12,停止 = 14)

标签: rdataframe

解决方案


如果您Map使用该seq函数erase_df创建要为每一行删除的行序列,然后将unlist它们全部放入一个向量中,您可以main_df使用该向量的负子集来删除给定范围内的行。

remove <- unlist(Map(seq, erase_df[[1]], erase_df[[2]]))

main_df[-remove,]
#    v1  v2     v3
# 1:  1 bla blabla
# 2:  2 bla blabla
# 3:  6 bla blabla
# 4:  7 bla blabla
# 5:  8 bla blabla
# 6: 11 bla blabla
# 7: 15 bla blabla

或者,对于更复杂的选项,可以更有效地处理更大的数据(尚未测试,只是猜测)

library(data.table)
setDT(main_df)
setDT(erase_df)

setkey(erase_df, starts, stops)
main_df[, v0 := v1]
for_anti <- 
  foverlaps(main_df, erase_df, by.x = c('v0', 'v1'), type = 'within',
            nomatch = NULL)

main_df[!for_anti, on = .(v1)]
#    v1  v2     v3 v0
# 1:  1 bla blabla  1
# 2:  2 bla blabla  2
# 3:  6 bla blabla  6
# 4:  7 bla blabla  7
# 5:  8 bla blabla  8
# 6: 11 bla blabla 11
# 7: 15 bla blabla 15

推荐阅读