计数个数



我有一个小程序问题,我似乎不能弄清楚。我想知道如何以一种优雅的方式计算从r

中每组不同值开始的序列中连续数字的数量以为例,我们有一个包含名字和数字的数据帧,我们希望找到最小化的数据帧,每个名字只保留一个条目,而在另一个数据帧中,每个名字

连续条目的数量
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个连续的进球,亨利有0,因为他没有1或任何有序的条目玛丽亚有2,因为她有从1到2的条目

names <- c("bob", "henry", "maria")
runs <- c("3", "0", "2")
output.df.from.1 <- data.frame(names, goals)

从3开始,Bob和maria都有一个0,但是Henry现在有一个3,因为他有3,4,5。

names <- c("bob", "henry", "maria")
runs <- c("0", "3", "0")
output.df.from.3 <- data.frame(names, goals)

我确信一定有一个简单的解决方案,但我还没有能够找到任何,但是我可能是在寻找错误的东西。

有人有什么建议吗?

这里有一个可能的解决方案。思路是1)首先找出每个人的(多个)连续数字,然后2)给定一个值,找出从该值开始的连续数字的长度。

我改变了您的示例数据一点,以考虑到每个人可以有多个连续数字的情况。(例如Bob现在有数字1,2,3,5,4,7,8,9,连续的组是1,2,3和7,8,9)

  1. 查找每个人的连续号码。第一组按names,在每一组中,找出goals的前一个数和后一个数。如果是连续的,则是previous_goal - current_goal = -1next_goal - current_goal = 1。注意我同时使用previous/next是为了在一个连续的组中保留所有的值。
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)
  1. 编写一个函数,计算从给定值开始的连续数字的长度。在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 

相关内容

  • 没有找到相关文章

最新更新