【问题标题】:How to remove ranges that are overlapping from duplicated values and keep associated values?如何从重复值中删除重叠的范围并保留关联值?
【发布时间】:2017-10-30 21:23:44
【问题描述】:

我有一个数据框,其中有一些重复的 x 值。这些值与一个范围相关联。应该删除重复的值(重复的 x 值)和具有重叠范围(两条线在低列和上列中重叠),但我想保留它们引用的值(val 列)。

library(dplyr)
df = data.frame(x=c("A","A","A","B","B","B","C"),
           low = c(-10,-5,100,100,200,300,10),
           up = c(2,3,200,150,250,350,20), 
           val = c(1,2,150,125,225,325,15))
df
  x low  up val
1 A -10   2   1
2 A  -5   3   2
3 A 100 200 150
4 B 100 150 125
5 B 200 250 225
6 B 300 350 325
7 C  10  20  15

如您所见,第 1 行和第 2 行重叠。看着the example here。我试图编写一个 dplyr 代码,但它没有给我预期的结果。该示例的不同之处在于我没有“合并” 2 个数据集。所以我不知道如何在包含重复值的数据集中测试不同的范围。我正在考虑将数据集中的重复值分组并单独测试它们。但由于它没有集成到 dplyr 功能中,我认为它不起作用。

df.gr = df %>% 
  group_by(x)

df.gr[with(df.gr, low <= up),]

最后,我想要这样的东西

  x low  up val
1 A -10   3 1,2
2 A 100 200 150
3 B 100 150 125
4 B 200 250 225
5 B 300 350 325
6 C  10  20  15

如您所见,对于重叠的范围,我保留了两个范围中的最低值和最高值。另外,我想“记住”“val”列中的值。这就是为什么我想在重叠的范围内得到 1,2。

此外,在我在这里引用的示例中,每个重复值只有 2 个范围。就我而言,我可能有 2 个或更多重复值。我想测试 any 重复值并测试它们的范围,看看它们是否重叠。

例如,

df = data.frame(x=c("A","A","A","A","B","B","B","C"),
           low = c(-10,-5,-2,100,100,200,300,10),
           up = c(2,3,4,200,150,250,350,20), 
           val = c(1,2,3,150,125,225,325,15))

df
  x low  up val
1 A -10   2   1
2 A  -5   3   2
3 A  -2   4   3
4 A 100 200 150
5 B 100 150 125
6 B 200 250 225
7 B 300 350 325
8 C  10  20  15

会给出:

  x low  up   val
1 A -10   4 1,2,3
2 A 100 200   150
3 B 100 150   125
4 B 200 250   225
5 B 300 350   325
6 C  10  20    15

我也尝试在 tidy 中使用spread 函数,但没有运气:

tidyr::spread(df,x,val)
  low  up   A   B  C
1 -10   2   1  NA NA
2  -5   3   2  NA NA
3  -2   4   3  NA NA
4  10  20  NA  NA 15
5 100 150  NA 125 NA
6 100 200 150  NA NA
7 200 250  NA 225 NA
8 300 350  NA 325 NA

基本上,如果我想使用它,我必须将 both 列作为键,但我不能这样做。此外,每个重复值的重叠数量会在创建不同列时使数据报变量的大小。所以我不知道如何处理这个......

【问题讨论】:

  • 你能在一个连接的行中多次拥有相同的val 值吗?比如1,2,2,3?
  • 不,对于 x 中相同的重复值,我不会有第二个相同的 val。
  • 我用更优雅的通用解决方案更新了我的答案

标签: r dplyr range summarization


【解决方案1】:

编辑:查看复杂递归解决方案的编辑历史

这是一个简单的解决方案,我们创建一个布尔值来标识组的变化,该布尔值上的 cumsum 给我们一个组标识符,我们在这个标识符上使用 group_by 然后汇总值。

library(dplyr)
# Example 1
df = data.frame(x=c("A","A","A","B","B","B","C"),
                low = c(-10,-5,100,100,200,300,10),
                up = c(2,3,200,150,250,350,20), 
                val = c(1,2,150,125,225,325,15))

df %>% arrange(x,low) %>%
  group_by(x,set = cumsum(c(TRUE,x[-1] != x[-n()] | low[-1] > up[-n()]))) %>%
  summarize(low=min(low),up=max(up),val=lst(val)) %>%
  print.data.frame

#   x set low  up  val
# 1 A   1 -10   3 1, 2
# 2 A   2 100 200  150
# 3 B   3 100 150  125
# 4 B   4 200 250  225
# 5 B   5 300 350  325
# 6 C   6  10  20   15

# Example 2
df = data.frame(x=c("A","A","A","A","B","B","B","C"),
                low = c(-10,-5,-2,100,100,200,300,10),
                up = c(2,3,4,200,150,250,350,20), 
                val = c(1,2,3,150,125,225,325,15))

df %>% arrange(x,low) %>%
  group_by(x,set = cumsum(c(TRUE,x[-1] != x[-n()] | low[-1] > up[-n()]))) %>%
  summarize(low=min(low),up=max(up),val=lst(val)) %>%
  print.data.frame

#   x set low  up     val
# 1 A   1 -10   4 1, 2, 3
# 2 A   2 100 200     150
# 3 B   3 100 150     125
# 4 B   4 200 250     225
# 5 B   5 300 350     325
# 6 C   6  10  20      15

【讨论】:

    【解决方案2】:

    这可以工作。我相信您需要在粘贴命令中使用“折叠”。

    output <- df %>% group_by(x) %>% summarise(low = min(low), up = max(up), values = paste(val,collapse=","))
    

    这会输出这个df:

    structure(list(x = structure(1:3, .Label = c("A", "B", "C"), class = "factor"), 
        low = c(-10, 100, 10), up = c(200, 350, 20), values = c("1,2,3,150", 
        "125,225,325", "15")), class = c("tbl_df", "tbl", "data.frame"
    ), .Names = c("x", "low", "up", "values"), row.names = c(NA, 
    -3L))
    
    # A tibble: 3 x 4
           x   low    up      values
      <fctr> <dbl> <dbl>       <chr>
    1      A   -10   200   1,2,3,150
    2      B   100   350 125,225,325
    3      C    10    20          15
    

    【讨论】:

    • 但是我不想总结所有重复值,我只想从重复值中删除它们的 范围 重叠。您的代码实际上正在删除所有重复的行,无论它们是否重叠......
    猜你喜欢
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2013-01-11
    • 2019-10-27
    • 2021-09-24
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多