【问题标题】:Counting the number of months from a column in a dataframe to each month in a sequence for multiple rows计算从数据框中的一列到多行序列中每个月的月数
【发布时间】:2016-07-29 13:58:11
【问题描述】:

这是我的第一篇文章,所以如果我不够具体,我深表歉意。

我有一个月份序列和一个包含大约 100 行的数据框,每行都有一个唯一标识符。每个标识符都与启动日期相关联。我正在尝试计算序列中每个月的每个唯一标识符自启动以来的月数。我曾尝试编写一个 for 循环来完成此操作,但没有成功。

以下示例:

# Build Example Data Frame #
x_example <- c("A","B","C","D","E")
y_example <- c("2013-10","2013-10","2014-04","2015-06","2014-01")
x_name <- "ID"
y_name <- "StartUp"
df_example <- data.frame(x_example,y_example)
names(df_example) <- c(x_name,y_name)

# Create Sequence of Months, Format to match Data Frame, Reverse for the For Loop #
base.date <- as.Date(c("2015-11-1"))
Months <- seq.Date(from = base.date , to = Sys.Date(), by = "month")
Months.1 <- format(Months, "%Y-%m")
Months.2 <- rev(Months.1)

# Create For Loop #
require(zoo)
for(i in seq_along(Months.2))
{
  for(j in 1:length(summary(as.factor(df_example$ID), maxsum = 100000)))
  {
   Active.Months <- 12 * as.numeric((as.yearmon(Months.2 - i) - as.yearmon(df_example$StartUp)))
  }
}

for 循环背后的想法是,对于 Months.2 序列中的每条记录,都会计算从每个唯一标识符的启动月份到该记录(月份日期)的月数。但是,这一直在踢回错误:

Months.2 中的错误 - i : 二元运算符的非数字参数

我不确定解决方案是什么,或者我是否为此正确使用了 for 循环。

在此先感谢您为解决此问题提供的任何帮助!

编辑:这就是我希望的预期结果(这只是一个示例,因为序列中有更多月份):

 ID Start Up Month 2015-11 2015-12 2015-12 2016-02 2016-03
1  A        2013-10      25      26      27      28      29
2  B        2013-10      25      26      27      28      29
3  C        2014-04      19      20      21      22      23
4  D        2015-06       5       6       7       8       9
5  E        2014-01      22      23      24      25      26

【问题讨论】:

  • 您能否发布一个您期望的输出示例,以便人们更容易正确回答您的问题?
  • 我添加了预期的输出,对此感到抱歉!

标签: r for-loop


【解决方案1】:

一种方法是首先使用zoo 包中的as.yearmon 来转换日期。然后我们简单地迭代几个月并从df_example中的那些中减去,

library(zoo)

df_example$StartUp <- as.Date(as.yearmon(df_example$StartUp))
Months.2 <- as.Date(as.yearmon(Months.2))

df <- as.data.frame(sapply(Months.2, function(i) 
                    round(abs(difftime(df_example$StartUp, i, units = 'days')/30))))
names(df) <- Months.2
cbind(df_example, df)

#  ID StartUp 2016-07 2016-06 2016-05 2016-04 2016-03 2016-02 2016-01 2015-12 2015-11
#1  A 2013-10      33      32      31      30      29      28      27      26      25
#2  B 2013-10      33      32      31      30      29      28      27      26      25
#3  C 2014-04      27      26      25      24      23      22      21      20      19
#4  D 2015-06      13      12      11      10       9       8       7       6       5
#5  E 2014-01      30      29      28      27      26      25      24      23      22

【讨论】:

    【解决方案2】:
    x_example <- c("A","B","C","D","E")
    y_example <- c("2013-10","2013-10","2014-04","2015-06","2014-01")
    y_example <- paste(y_example,"-01",sep = "")
    
    # past on the "-01" because I want the later function to work. 
    
    x_name <- "ID"
    y_name <- "StartUp"
    df_example <- data.frame(x_example,y_example)
    names(df_example) <- c(x_name,y_name)
    
    
    base.date <- as.Date(c("2015-11-01"))
    Months <- seq.Date(from = base.date , to = Sys.Date(), by = "month")
    Months.1 <- format(Months, "%Y-%m-%d")
    Months.2 <- rev(Months.1)
    
    monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); lt$year*12 + lt$mon } 
    mondf <- function(d1, d2) {monnb(d2) - monnb(d1)}
    
    NumofMonths <- abs(mondf(df_example[,2],Sys.Date()))
    
    n = max(NumofMonths)
    
    # sequence along the number of months and get the month count. 
    
    monthcount <- (t(sapply(NumofMonths, function(x) pmax(seq((x-n+1),x, +1), 0) )))
    monthcount <- data.frame(monthcount[,-(1:24)])
    names(monthcount) <- Months.1
    
    finalDataFrame <- cbind.data.frame(df_example,monthcount)
    

    这是您指定的最终数据框:

      ID    StartUp 2015-11-01 2015-12-01 2016-01-01 2016-02-01 2016-03-01 2016-04-01 2016-05-01 2016-06-01 2016-07-01
    1  A 2013-10-01         25         26         27         28         29         30         31         32         33
    2  B 2013-10-01         25         26         27         28         29         30         31         32         33
    3  C 2014-04-01         19         20         21         22         23         24         25         26         27
    4  D 2015-06-01          5          6          7          8          9         10         11         12         13
    5  E 2014-01-01         22         23         24         25         26         27         28         29         30
    

    总体思路是我们计算月数并使用序列函数创建一个月数计数器,直到我们得到当前月份。

    【讨论】:

    • 感谢您将这些放在一起,这真的很有帮助!
    • @DW1 如果您认为这是最佳答案,请点击“复选”标记
    猜你喜欢
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 2020-10-18
    • 2020-09-01
    相关资源
    最近更新 更多