有没有办法创建与 R 中的条件匹配的多列总和范围?

Is there a way to create a range of sum of multiple columns matching a condition in R?

我有一个数据框,其中包含一个实验性的 CONDITION,它具有一个确定的 INDEX。每个实验都有一个 NAME-A 关联和一个 NAME_B 对应于特定的 NAME_A.

我的主要objective是通过CONDITION总结NAME-ANAME-B的总数,方法是考虑两者之间INDEX值的差异创建一个范围连续 NAME_A ,即相同 CONDITION 的索引之间的差异不应大于 400 (INDEX[i+1] - INDEX[i] < 400 ).

可能的场景是 NAME_A 可以复制,但不能 NAME_BNAME_A 可以没有 NAME_B 关联,因此列之间的计数可能不同。

这里我举个例子,a是我的输入数据,b应该是输出。

a <- data.frame(c(1,2,2,2,2,3),c(1,1,50,400,900,1),c("A","B","B","C","D","E"),
                c("X1","X2","X3","X4","X5",NA))
colnames(a) <- c("CONDITION","INDEX","NAME_A","NAME_B")

数据

  CONDITION INDEX NAME_A NAME_B
1         1     1      A     X1
2         2     1      B     X2
3         2    50      B     X3
4         2   400      C     X4
5         2   900      D     X5
6         3     1      E   <NA>

期望输出

b <- data.frame(c(1,2,2,3),c(1,1,900,1),c(1,400,900,1),c("A","B, C","D","E"),c(1,2,1,1),
                c("X1","X2, X3, X4","X5",NA),c(1,3,1,0))
colnames(b) <- c("CONDITION","INDEX_MIN","INDEX_MAX",
                 "NAME_A","COUNT_A","NAME_B","COUNT_B")

  CONDITION INDEX_MIN INDEX_MAX NAME_A COUNT_A     NAME_B COUNT_B
1         1         1         1      A       1         X1       1
2         2         1       400   B, C       2 X2, X3, X4       3
3         2       900       900      D       1         X5       1
4         3         1         1      E       1       <NA>       0

我的问题是,我已经为 NAME-ANAME-B 分别做了这个,但如示例所示,有时 NAME-A 没有 NAME-B 关联,所以结果范围 windows 在数据帧之间分布不均,因此需要进一步手动编辑。

dplyr可以group_byCONDITION,然后用summarise确定其他栏目。值得注意的是,我使用下划线而不是连字符列名称(否则,如果使用非标准名称,请将它们用反引号括起来)。

为了解决行间 INDEX 不大于 400 的差异,您可以使用 cumsum 分配一个 GROUP 编号,当 INDEX 的差异超过 400 时,它将在给定的 CONDITION 内递增。然后您可以使用这在总结之前的 group_by 语句中。

请注意,n_distinct(NAME_B, na.rm = TRUE) 可以用 sum(!is.na(NAME_B)) 代替,因为 NAME_B 不能重复。

library(dplyr)

a %>%
  group_by(CONDITION) %>%
  group_by(GROUP = cumsum(c(1, diff(INDEX) > 400)), .add = TRUE) %>%
  summarise(
    INDEX_MIN = min(INDEX),
    INDEX_MAX = max(INDEX),
    COUNT_A = n_distinct(NAME_A),
    NAME_A = toString(unique(NAME_A)), 
    COUNT_B = n_distinct(NAME_B, na.rm = TRUE),
    NAME_B = toString(NAME_B)
  )

输出

  CONDITION GROUP INDEX_MIN INDEX_MAX COUNT_A NAME_A COUNT_B NAME_B    
      <dbl> <dbl>     <dbl>     <dbl>   <int> <chr>    <int> <chr>     
1         1     1         1         1       1 A            1 X1        
2         2     1         1       400       2 B, C         3 X2, X3, X4
3         2     2       900       900       1 D            1 X5        
4         3     2         1         1       1 E            0 NA

数据

a <- structure(list(CONDITION = c(1, 2, 2, 2, 2, 3), INDEX = c(1, 
1, 50, 400, 900, 1), NAME_A = c("A", "B", "B", "C", "D", "E"), 
    NAME_B = c("X1", "X2", "X3", "X4", "X5", NA)), class = "data.frame", row.names = c(NA, 
-6L))