【问题标题】:Is there a way to create a range of sum of multiple columns matching a condition in R?有没有办法在 R 中创建匹配条件的多个列的总和范围?
【发布时间】:2021-08-28 17:00:00
【问题描述】:

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

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

可能的场景是NAME_A 可以复制,但NAME_B 不能。 NAME_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,因此结果范围窗口在数据帧之间分布不均,因此需要进一步的手动版本。

【问题讨论】:

    标签: r dataframe dplyr summarize


    【解决方案1】:

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

    要解决行间 INDEX 中不大于 400 的差异,您可以使用 cumsum 分配一个 GROUP 编号,当 INDEX 中的差异超过 400 时,该编号将在给定 CONDITION 内递增。然后您可以在您的 @ 987654325@总结前的声明。

    请注意,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))
    

    【讨论】:

    • 它工作了,但缺少一些东西。我想使用INDEX创建一个范围,假设当CONDITION中索引之间的差异不大于400时形成一个特定范围,然后在该范围内计算NAME-ANAME-B。跨度>
    • @PauloAlvarez 您是否要对每个 CONDITION/NAME_A 组合进行检查,查看 INDEX 中的范围,然后添加数据行以确保 INDEX 中的最大差异不超过 400?因此,例如,如果 CONDITION 为 2,NAME_A 为 B,则差异为 50;但如果它是 600,那么会创建两行,其中 INDEX 为 400,NAME_B 不同,所以 INDEX 范围是 1-400 和 400-600?
    • 谢谢你,我意识到我提出的问题真的错了,所以我编辑了。你明白我在期待什么。一般的想法是在索引之间产生差异以创建新条件,然后总结每个原始条件有多少个NAME_A和NAME_B。
    • @PauloAlvarez 请查看编辑后的答案 - 这是否实现了您的目标?
    猜你喜欢
    • 2018-05-04
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多