*
请注意,列名中不能有 a (请参阅 参考资料?make.names
)。这是一个基本的方法:
拆分Year_store
为两个单独的列Year
并Store
在您的数据框中;目前它包含两种完全不同的数据,您实际上需要分别处理它们。
创建一个NextYear
列,定义为Year + 1
做一NextStore
列,指定店铺编码匹配Customer_Id
且与Year
本行相同NextYear
,指定NA
是否没有客户次年来店的记录,不符合要求则报错规格(对于第二年首先访问的商店模棱两可)。
NextStore
去掉is中的任何行NA
,并将NextYear
和NextStore
列组合成一NextYear_NextStore
列。
Year_store
通过和NextYear_NextStore
列总结您的数据框,例如ddply
在plyr
包中使用。
一些样本数据:
# same example data as question
customer.df <- data.frame(Customer_Id = c(1, 1, 1, 2, 2, 2),
Year_Store = c("2010_A", "2011_B", "2012_C", "2010_A", "2011_B", "2012_D"),
stringsAsFactors = FALSE)
# alternative data should throw error, customer 2 is inconsistent in 2011
badCustomer.df <- data.frame(Customer_Id = c(1, 1, 1, 2, 2, 2),
Year_Store = c("2010_A", "2011_B", "2012_C", "2010_A", "2011_B", "2011_D"),
stringsAsFactors = FALSE)
和一个实现:
require(plyr)
splitYearStore <- function(df) {
df$Year <- as.numeric(substring(df$Year_Store, 1, 4))
df$Store <- as.character(substring(df$Year_Store, 6))
return(df)
}
findNextStore <- function(df, matchCust, matchYear) {
matchingStore <- with(df,
df[Customer_Id == matchCust & Year == matchYear, "Store"])
if (length(matchingStore) == 0) {
return(NA)
} else if (length(matchingStore) > 1) {
errorString <- paste("Inconsistent store results for customer",
matchCust, "in year", matchYear)
stop(errorString)
} else {
return(matchingStore)
}
}
tabulateTransitions <- function(df) {
df <- splitYearStore(df)
df$NextYear <- df$Year + 1
df$NextStore <- mapply(findNextStore, matchCust = df$Customer_Id,
matchYear = df$NextYear, MoreArgs = list(df = df))
df$NextYear_NextStore <- with(df, paste(NextYear, NextStore, sep = "_"))
df <- df[!is.na(df$NextStore),]
df <- ddply(df, .(Source = Year_Store, Target = NextYear_NextStore),
summarise, No_Customers = length(Customer_Id))
return(df)
}
结果:
> tabulateTransitions(customer.df)
Source Target No_Customers
1 2010_A 2011_B 2
2 2011_B 2012_C 1
3 2011_B 2012_D 1
> tabulateTransitions(badCustomer.df)
Error in function (df, matchCust, matchYear) :
Inconsistent store results for customer 2 in year 2011
没有尝试优化;如果您的数据集很大,那么也许您应该研究一个data.table
解决方案。