有没有办法创建与 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-A
和NAME-B
的总数,方法是考虑两者之间INDEX
值的差异创建一个范围连续 NAME_A
,即相同 CONDITION
的索引之间的差异不应大于 400 (INDEX[i+1] - INDEX[i] < 400 ).
可能的场景是 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-A
和 NAME-B
分别做了这个,但如示例所示,有时 NAME-A
没有 NAME-B
关联,所以结果范围 windows 在数据帧之间分布不均,因此需要进一步手动编辑。
用dplyr
可以group_by
CONDITION,然后用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))
我有一个数据框,其中包含一个实验性的 CONDITION
,它具有一个确定的 INDEX
。每个实验都有一个 NAME-A
关联和一个 NAME_B
对应于特定的 NAME_A
.
我的主要objective是通过CONDITION
总结NAME-A
和NAME-B
的总数,方法是考虑两者之间INDEX
值的差异创建一个范围连续 NAME_A
,即相同 CONDITION
的索引之间的差异不应大于 400 (INDEX[i+1] - INDEX[i] < 400 ).
可能的场景是 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-A
和 NAME-B
分别做了这个,但如示例所示,有时 NAME-A
没有 NAME-B
关联,所以结果范围 windows 在数据帧之间分布不均,因此需要进一步手动编辑。
用dplyr
可以group_by
CONDITION,然后用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))