【问题标题】:Summing columns with string match on dates对日期字符串匹配的列求和
【发布时间】:2017-09-19 16:04:16
【问题描述】:

我有一个数据框 df,其中包含一个 ID 变量和每日日期(格式 XYYYYMMDD)作为列标题:

ID <- c(101,102,203,207,209)
X20170101 <- c(1,NA,NA,2,1)
X20170102 <- c(NA,1,1,1,NA)
X20170103<-c(NA,NA,NA,2,1)
X20170201<-c(NA,2,NA,NA,1)
X20170202<-c(NA,1,1,NA,NA)
X20170301<-c(NA,1,NA,NA,NA)
df <- data.table(ID,X20170101,X20170102,X20170103,X20170201,X20170202,X20170301)

 ID X20170101 X20170102 X20170103 X20170201 X20170202 X20170301
101         1        NA        NA        NA        NA        NA
102        NA         1        NA         2         1         1
203        NA         1        NA        NA         1        NA
207         2         1         2        NA        NA        NA
209         1        NA         1         1        NA        NA

对于每个 ID,我想汇总属于同一月份的所有日期/列。如果yyyymm是前三个月的字符串向量

yyyymm <- c("X201701","X201702","X201703")

我想获取数据框 want,其中 yyyymm 中的字符串作为列的标题。那就是:

 ID X201701 X201702 X201703
101       1      NA      NA
102       1       3       1
203       1       1      NA
207       5      NA      NA
209       2       1      NA

我的想法是避免重塑我的数据集的格式,并使用函数 lapply 和 grepl 来部分匹配字符串,但我遗漏了一些东西。

test = lapply(df, function(x) colSums(df[,grepl(x, names(df))]))

非常感谢。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    这是一个使用lubridate 包解析日期和split.default 将data.frame 基于同一月份分组

    library(lubridate)
    factors = sapply(ymd(gsub("X", "", names(df)[-1])), function(x)
        paste0(year(x), sprintf("%02d", as.integer(month(x)))))
    data.frame(df[,1],
               lapply(split.default(df[,-1], factors), function(x)
                   rowSums(x, na.rm = TRUE) * (NA^(rowSums(is.na(x)) == NCOL(x)))))
    #   ID X201701 X201702 X201703
    #1 101       1      NA      NA
    #2 102       1       3       1
    #3 203       1       1      NA
    #4 207       5      NA      NA
    #5 209       2       1      NA
    

    【讨论】:

      【解决方案2】:

      您是否有不想传播数据的原因?

      library(tidyverse)
      want <- df %>%
                gather(key, value, -ID) %>%
                mutate(key = substr(key, 1, 7)) %>%
                group_by(ID, key) %>%
                summarise(value = sum(value, na.rm=TRUE)) %>%
                spread(key, value)
      
      # A tibble: 5 x 4
      # Groups:   ID [5]
           ID X201701 X201702 X201703
      * <dbl>   <dbl>   <dbl>   <dbl>
      1   101       1       0       0
      2   102       1       3       1
      3   203       1       1       0
      4   207       5       0       0
      5   209       2       1       0
      

      【讨论】:

        猜你喜欢
        • 2018-03-03
        • 1970-01-01
        • 1970-01-01
        • 2019-12-30
        • 1970-01-01
        • 2017-06-05
        • 2021-10-17
        • 1970-01-01
        • 2017-11-04
        相关资源
        最近更新 更多