如何在 r 中使列动态化
How to make column dynamic in r
以上代码计算群组保留率。队列是加入的月份。因此,该代码计算了 2015 年 5 月加入的客户数量,以及每月活跃的客户数量。最终输出存储在数据框 df1 中(如下所示)
我需要帮助创建动态列名,这些名称目前在 ddply 函数中是硬编码的。 M0 表示加入月份,M1 表示加入后第 1 个月,M2 表示加入后 2 个月,M(n) 应该是变量。这可以通过从最早的加入日期减去最远的到期日期来计算。
不幸的是,我无法动态地自动计算 M0 到 M(n) 的范围。
这是我的代码转储,它可以工作但不是最佳的,因为我已将 M0 到 M3 硬编码为 ddply 函数中的变量。因此,如果我的输入数据有一个订阅期超过 5 个月的客户,我的代码将失败。
代码的输入是以下虚拟数据。
customer dj exp
abc 01/05/15 25/06/15
efg 01/05/15 25/07/15
ghd 01/05/15 25/07/15
mkd 01/06/15 25/07/15
kskm 01/06/15 05/08/15
可重现的代码。
library(zoo)
library(plyr)
customer<-c("abc","efg","ghd","mkd","kskm")
dj<-c("2015-05-01", "2015-05-01", "2015-05-01","2015-06-01","2015-06-01")
exp<-c("2015-06-25", "2015-07-25", "2015-07-25","2015-07-01","2015-08-05")
data.frame(customer,dj,exp)
df$dj <- as.Date(df$dj,"%d/%m/%y")
df$exp <- as.Date(df$exp,"%d/%m/%y")
# The data in the file has different variable names than your example data
# so I'm changing them to match
names(df)[1:3] <- c("customer","dj","exp")
# Make a variable called Cohort that contains only the year and month of joining
# as.yearmon() comes from the 'zoo' package
df$Cohort <- as.yearmon(df$dj)
# Calculate the difference in months between date of expiry and date of joining
df$MonthDiff <- ceiling((df$exp-df$dj)/30)
#df$MonthDiff <- 12*(as.yearmon(df$exp+months(1))-df$Cohort)
range<-as.integer(ceiling((max(df$exp)-min(df$dj)))/30)
# Use ddply() from the 'plyr' package to get the frequency of subjects that are
# still active after 0, 1, 2, and 3 months.
df1 <- ddply(df,.(Cohort),summarize,
M0 = sum(MonthDiff > 0),
M1 = sum(MonthDiff > 1),
M2 = sum(MonthDiff > 2),
M3 = sum(MonthDiff > 3)
)
df1
df1
Cohort M0 M1 M2 M3
1 May 2015 3 3 2 0
2 Jun 2015 2 2 1 0
以上是输出工作输出。要求是使列 M0 到 M3 动态
尝试在创建后插入这个 range
:
for(i in 0:range) df <- within(df,assign(paste0("M",i),MonthDiff>i))
df1 <- ddply(df,.(Cohort),function(x) colSums(x[,paste0("M",0:range)]))
df1
# Cohort M0 M1 M2 M3
# 1 May 2015 3 3 2 0
# 2 Jun 2015 2 1 1 0
以上代码计算群组保留率。队列是加入的月份。因此,该代码计算了 2015 年 5 月加入的客户数量,以及每月活跃的客户数量。最终输出存储在数据框 df1 中(如下所示)
我需要帮助创建动态列名,这些名称目前在 ddply 函数中是硬编码的。 M0 表示加入月份,M1 表示加入后第 1 个月,M2 表示加入后 2 个月,M(n) 应该是变量。这可以通过从最早的加入日期减去最远的到期日期来计算。
不幸的是,我无法动态地自动计算 M0 到 M(n) 的范围。
这是我的代码转储,它可以工作但不是最佳的,因为我已将 M0 到 M3 硬编码为 ddply 函数中的变量。因此,如果我的输入数据有一个订阅期超过 5 个月的客户,我的代码将失败。
代码的输入是以下虚拟数据。
customer dj exp
abc 01/05/15 25/06/15
efg 01/05/15 25/07/15
ghd 01/05/15 25/07/15
mkd 01/06/15 25/07/15
kskm 01/06/15 05/08/15
可重现的代码。
library(zoo)
library(plyr)
customer<-c("abc","efg","ghd","mkd","kskm")
dj<-c("2015-05-01", "2015-05-01", "2015-05-01","2015-06-01","2015-06-01")
exp<-c("2015-06-25", "2015-07-25", "2015-07-25","2015-07-01","2015-08-05")
data.frame(customer,dj,exp)
df$dj <- as.Date(df$dj,"%d/%m/%y")
df$exp <- as.Date(df$exp,"%d/%m/%y")
# The data in the file has different variable names than your example data
# so I'm changing them to match
names(df)[1:3] <- c("customer","dj","exp")
# Make a variable called Cohort that contains only the year and month of joining
# as.yearmon() comes from the 'zoo' package
df$Cohort <- as.yearmon(df$dj)
# Calculate the difference in months between date of expiry and date of joining
df$MonthDiff <- ceiling((df$exp-df$dj)/30)
#df$MonthDiff <- 12*(as.yearmon(df$exp+months(1))-df$Cohort)
range<-as.integer(ceiling((max(df$exp)-min(df$dj)))/30)
# Use ddply() from the 'plyr' package to get the frequency of subjects that are
# still active after 0, 1, 2, and 3 months.
df1 <- ddply(df,.(Cohort),summarize,
M0 = sum(MonthDiff > 0),
M1 = sum(MonthDiff > 1),
M2 = sum(MonthDiff > 2),
M3 = sum(MonthDiff > 3)
)
df1
df1
Cohort M0 M1 M2 M3
1 May 2015 3 3 2 0
2 Jun 2015 2 2 1 0
以上是输出工作输出。要求是使列 M0 到 M3 动态
尝试在创建后插入这个 range
:
for(i in 0:range) df <- within(df,assign(paste0("M",i),MonthDiff>i))
df1 <- ddply(df,.(Cohort),function(x) colSums(x[,paste0("M",0:range)]))
df1
# Cohort M0 M1 M2 M3
# 1 May 2015 3 3 2 0
# 2 Jun 2015 2 1 1 0