• R语言
  • 如何将一行代表持续天数的序列 4,3,1,1,0 转换成每天出现频次 1,2,2,3,0

CMCai0104
但是我不知道怎么构建这个矩阵啊 就对R的掌握程度还没有达到可以编出来的地步

Date <- c("06-01","06-02","06-03","06-04","06-04")
Last_day <- c(4,3,1,1,0)
Data1 <- data.frame(Date,Last_day)
Data1$index <- c(1:nrow(Data1))

matri <- apply(Data1, 1, function(item){
  start_zero_num <- as.numeric(item[[3]])-1
  one_num <- as.numeric(item[[2]])
  end_zero_num <- nrow(Data1) - start_zero_num - one_num
  if(end_zero_num<0){end_zero_num <- 0}
  vect <- c(rep(0, start_zero_num), rep(1, one_num), rep(0, end_zero_num))[1:nrow(Data1)]
  return(vect)
})

Data1$Count_day <- apply(matri, 1, sum)

大概写了下,细节自己完善吧!

这种还是很简单的,多练习吧,实在不行用for循环也可以,自己用,慢又无所谓。

在2楼我理解有点偏差答案写错了,不过重新用lubridate来一发:

核心是使用date+ duration构建完整的合集,比如06-01持续4天就生成06-01到06-04

这样完整的时间合集就可以table统计频次了。
另外好处就是跨月份的话问题也不大,不同月份天数不一样什么的细节问题要处理好的话还是建议用专门处理时间序列的包来做。

library(lubridate)

get_series = function(start, duration){
  start= lubridate::as_datetime(start, format="%m-%d")
  end = start + days(duration-1)
  if(start<=end){
    return(seq(start, end, by="1 day"))
  }
  else{
    return(NULL)
  }
  
}

Date <- c("06-01","06-02","06-03","06-04","06-04")
Last_day <- c(4,3,1,1,0)
Data1 <- data.frame(Date,Last_day, stringsAsFactors=FALSE)

rslt = lapply(1:nrow(Data1), function(i){
  rslt = get_series(Data1$Date[i], Data1$Last_day[i])
  rslt=as.character(rslt)
  return(rslt)
})

table(unlist(rslt))
#> 
#> 2019-06-01 2019-06-02 2019-06-03 2019-06-04 
#>          1          2          3          3

CMCai0104
我尝试了如下代码

Row1_1 <- matrix(0,nrow=95,ncol=95)
for (i in 1:95){
  k <-  Row[1,i]
  p <- i+k-1
  if (k==0){
    Row1_1[i,] <- 0
    }
    else{
      if (p<=95){
        Row1_1[i,i:p] <- 1
      }
      else{
        Row1_1[i,i:95] <- 1
      }
    }
  }

但是出现了这个错误
Error in i:p : NA/NaN argument
就不知道那里不对。
Row是1*95的时间序列数据

    代码有问题,大概写一下,大神帮忙完善吧

    library(lubridate)
    library(tidyverse)
    date = c("2019-06-01", "2019-06-02","2019-06-03","2019-06-04","2019-06-04")
    last_day = c(4,3,1,1,0)
    df = data.frame(date, last_day)
    df$date  = ymd(df$date)
    
    for (i in 1:length(df) {
      result <- 
        ifelse(df$last_day[i] > 1, df$date[i] + seq(0:(df$last_day[i] - 1)),
               ifelse(df$last_day[i] == 1, df$date[i], NULL
                      )
               )
      print(result)
    }
    table(result)

      如果我没理解错的话,这不就是个 seq + mapply + table 的问题嘛……

      # 构建数据:
      date_df <- data.frame(start = c("06-01","06-02","06-03","06-04","06-04"), 
                            duration = c(4,3,1,1,0))
      # 识别日期:
      date_df$ystart <- as.Date(paste0('2019-', date_df$start))
      # 生成所有日期:
      date_ls <- mapply(function(x1, x2) format(seq(from = x1, length.out = x2, by = 1), '%m-%d'), 
                        date_df$ystart, date_df$duration)
      # 统计频次:
      table(unlist(date_ls))
        2 年 后

        过来擦个屁股 。

        Date <- c("06-01", "06-02", "06-03", "06-04", "06-04")
        Last_day <- c(4, 3, 1, 1, 0)
        Data1 <- data.frame(Date, Last_day)
        
        library(tidyverse)
        library(lubridate)
        Data1 %>% 
          mutate(
            Date = ymd(str_c("2021", Date)),
            reps = map2(
              Date, 
              Last_day,
              ~ seq(.x, by = 1, length.out = .y)          
            )
          ) %>% 
          unnest(reps) %>% 
          count(reps)