计算从数据框中的列到多个行的序列中的每个月的月数

时间:2016-07-29 13:58:12

标签: r for-loop

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

我有一个月的序列和一个大约有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序列中的每个记录,将计算从每个唯一标识符的Start Up月开始的该记录(月日期)的月数。然而,这一直在踢回错误:

  

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

2 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是首先使用as.yearmon包中的zoo来转换日期。然后我们只需迭代几个月,然后从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

答案 1 :(得分:0)

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

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