【问题标题】:Count number of. consecutive occurrences in sequence per group in R数数。 R中每组按顺序连续出现
【发布时间】:2021-12-09 09:52:16
【问题描述】:

我有一个小程序问题,我似乎无法弄清楚。 我想知道如何以优雅的方式计算从 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 个连续条目,亨利有 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)

我确信必须有一个简单的解决方案,但我无法找到任何解决方案,但是我可能正在寻找错误的东西。

有人有什么建议吗?

【问题讨论】:

  • 您的goals 列是字符串而不是数字是否有特殊原因?似乎您想将它们计为数字,但是您以制作框架的方式明确地将它们转换为字符串。也许您应该只使用 input.df &lt;- data.frame(names, goals) 而不是不必要的复杂 as.data.frame(cbind(..)) 方法(这很少必要/有用)?
  • henry 有一个 1,即使条目是无序的。你的规则有点不清楚,你是说每个名字的第一个目标必须是 1 并且你只计算每行递增 1 的那些?
  • 嗨,r2evans,很抱歉不清楚规则,是的,这正是我的意思。这里没有具体原因说明为什么它应该是一个字符串而不是数字我将编辑问题
  • 您想要数据帧列表作为最终输出吗?为什么只检查 1 和 3 的连续目标值,而不检查 2、4、5、6 等其他数字?

标签: r numbers sequence data-wrangling find-occurrences


【解决方案1】:

这是您答案的可能解决方案。思路是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。请注意,我同时使用了上一个/下一个,以便保留连续组中的所有值。
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 

【讨论】:

    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2019-08-12
    • 2021-09-16
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多