提问人:user547928359 提问时间:10/23/2021 最后编辑:user547928359 更新时间:10/23/2021 访问量:284
计数数。R 中每组按顺序连续出现
Count number of. consecutive occurrences in sequence per group in R
问:
我有一个小程序问题,我似乎无法弄清楚。 我想知道我如何以一种优雅的方式计算序列中连续数字的数量,从 r 中每组的不同值开始
例如,我们有一个包含名称和数字的数据框,并希望找到最小化数据框,每个名称仅保留 1 个条目,而在另一个数据框中,每个名称仅保留连续条目数
names <- c(rep("bob",5), rep("henry",5), rep("maria",5))
goals <- c(1,2,3,5,4, 4,3,4,5,2, 1,2,4,6,5)
input.df <- data.frame(names, goals)
因此,从 1 开始,输出数据框将如下图所示,其中“Bob”有一个 3,因为他有 1 到 3 个连续进球条目,Henry 有 0,因为他没有 1 或任何有序条目,Maria 有 2,因为她有 1 到 2 的条目
names <- c("bob", "henry", "maria")
runs <- c("3", "0", "2")
output.df.from.1 <- data.frame(names, goals)
从 3 开始,鲍勃和玛丽亚都会得到 0,但亨利现在会得到 3,因为他有 3、4、5。
names <- c("bob", "henry", "maria")
runs <- c("0", "3", "0")
output.df.from.3 <- data.frame(names, goals)
我确信一定有一个简单的解决方案,但我找不到任何解决方案,但是我可能在寻找错误的东西。
有人有建议吗?
答:
0赞
Xiang
10/23/2021
#1
这是您的答案的可能解决方案。这个想法是 1) 首先找出每个人的(多个)连续数字,然后 2) 给定一个值,找出从该值开始的连续数字的长度。
我稍微更改了您的示例数据,以考虑到每个人可以有多个连续数字的情况。(例如,Bob 现在有数字 1、2、3、5、4、7、8、9,连续的组是 1、2、3 和 7、8、9)。
- 找到每个人的连续数字。第一组 ,在每个组中,找到 的上一个和下一个数字。如果是连续的,则 either 或 .注意:我同时使用上一个/下一个,以便将所有值保留在一个连续的组中。
names
goals
previous_goal - current_goal = -1
next_goal - current_goal = 1
library(tidyverse)
names <- c(rep("bob",8), rep("henry",5), rep("maria",5))
goals <- c(1,2,3,5,4, 7,8,9, 4,3,4,5,2, 1,2,4,6,5)
df1 <- data.frame(names, goals)
df2 <- df1 %>%
group_by(names) %>%
mutate(goals_lag = lag(goals) - goals) %>%
mutate(goals_lead = lead(goals) - goals) %>%
filter(goals_lag == -1 | goals_lead == 1) %>%
select(-goals_lag, -goals_lead)
- 编写一个函数来计算从给定值开始的连续数字的长度。 在 bob 的情况下,有两个连续的组 1、2、3 和 7、8、9。如果给定值为 1,则长度应为 3 而不是 6。因此,我们需要知道不同连续组的起始位置在哪里(组 7、8、9 的起始索引为 4)。找到给定值的位置后(如果给定值为 1,则索引为 1),我们可以使用下一组的起始位置减去给定值位置(在这种情况下为 4-1=3),这就是计算长度的方法)。
cons_len <- function(df, name, start_val){
# take goals as a vector
vec <- (df %>% filter(names == name))$goals
# find the starting positions of different groups
vec_stops <- which( (vec - c(vec[1] - 1, vec[-length(vec)])) != 1)
# find the index of the given value
vec_start <- which(vec == start_val)
# if not find the value, return 0
if (length(vec_start)==0) {
return(0)
# if there is only one group of consecutive numbers
} else if (length(vec_stops) == 0) {
return(length(vec) - vec_start + 1)
} else {
# if there are multiple groups of consecutive numbers
len <- vec_stops[vec_start <= vec_stops][1] - vec_start
return(ifelse(len == 1, 0, len))
}
}
# apply to each name
sapply(unique(df1$names), function(name) cons_len(df2, name, 1))
# bob henry maria
# 3 0 2
sapply(unique(df1$names), function(name) cons_len(df2, name, 3))
# bob henry maria
# 0 3 0
评论
goals
input.df <- data.frame(names, goals)
as.data.frame(cbind(..))
henry
具有 1,即使条目不按顺序排列。你的规则有点不清楚,你是说每个名字都必须是第一个目标,你只计算每行递增 1 的那些?1