我有一个包含3列的R数据框
我试图找到一种优雅的方式(理想情况下)在指定的时间范围内找到值增加或减少X%的位置。例如,我想知道数据中所有点在1周内价值增加50%或更多。
是否有任何内置的软件包功能,我可以只传递一个百分比和几天,并让它返回数据框中的哪些行匹配?
沿着这些方向的东西(下面的伪代码):
RowsThatareAMatch <- findmatches(date=MyDF$Timestamp, grouping=MyDF$Category, data=MyDF$Value, growth=0.5, range=7)
让我失望的是,我希望它为每个具有值的类别返回行,而不仅仅是查看数据框中的每个值。因此,如果A类和A类在我的数据中,B在7天内增长了50%或更多8次,我想要返回这些行,如果类别为C,D,&amp; E并不是每个人都有这种增长,我根本不想要从这些类别返回数据。
现在我正在考虑系统地将数据框拆分为每个类别的多个数据框,然后对每个单独的数据框进行分析。虽然这种方法可行,但有些事情告诉我R更容易实现这一点。
思想?
编辑:理想情况下,我要查找的是一个包含3列的数据框,并为我的数据中的每个匹配添加1行。
根据我对RI的经验,需要确定每个分组的行号,然后我可以从原始数据框中提取上述数据,但是如果有任何好的方法可以直接进入上面的输出那太棒了!
示例数据
所以我有这样的CSV:
Timestamp,Category,Value
2015-01-01,A,1
2015-01-02,A,1.2
2015-01-03,A,1.3
2015-01-04,A,8
2015-01-05,A,8.2
2015-01-06,A,9
2015-01-07,A,9.2
2015-01-08,A,10
2015-01-09,A,11
2015-01-01,B,12
2015-01-02,B,12.75
2015-01-03,B,15
2015-01-04,B,60
2015-01-05,B,62.1
2015-01-06,B,63
2015-01-07,B,12.3
2015-01-08,B,10
2015-01-09,B,11
2015-01-01,C,100
2015-01-02,C,100000
2015-01-03,C,200
2015-01-04,C,350
2015-01-05,C,780
2015-01-06,C,780.2
2015-01-07,C,790
2015-01-08,C,790.3
2015-01-09,C,791
2015-01-01,D,0.5
2015-01-02,D,0.8
2015-01-03,D,0.83
2015-01-04,D,2
2015-01-05,D,0.01
2015-01-06,D,0.03
2015-01-07,D,0.99
2015-01-08,D,1.23
2015-01-09,D,5
我会把它读成R这样的
df <- read.csv("CategoryMeasurements.csv", header=TRUE)
答案 0 :(得分:0)
假设您的data.frame被称为df
,您可以使用data.table
执行此类操作,这会创建一个读取&#34;增加超过50%的新行&#34;如果价值增长50%或更多(然后你可以过滤):
lag <- function(x, n) c(rep(NA, n), x[1:(length(x) - n)])
library(data.table)
setDT(df)[, ifelse(value/lag(value, 1) - 1 > 0.5, "increase over 50%", "Other"), by = category]
答案 1 :(得分:0)
嗯,我不确定它有多优雅,但是它有效,并且在将数据帧传递给我的函数之前我必须按类别进行子集,并且需要创建一个循环或使用其中一个apply函数来将每个类别传递给我的函数,但它应该完成工作。
Mydf <- read.csv("CategoryMeasurements.csv", header=TRUE)
GetIncreasesWithinRange <- function(df, growth, days ) {
# df = data frame with data you want processed. 1st column should be a date, 2nd column should be the data.
# growth = % of growth you are looking for in the data
# days = the number of days that the growth should occur in to be a match.
df <- df[order(df[,1]), ] # Sort the df by the date column. This is important for the loop logic.
# Initialize empty data frame to hold results that will be returned from this funciton.
ReturnDF <- data.frame( StartDate=as.Date(character()),
EndDate=as.Date(character()),
Growth=double(),
stringsAsFactors=FALSE)
TotalRows = nrow(df)
for(i in 1:TotalRows) {
StartDate <- toString(df[i,1])
StartValue <- df[i,2]
for(x in i:(TotalRows)) {
NextDate <- toString(df[x,1])
DayDiff <- as.numeric(difftime(NextDate ,StartDate , units = c("days")))
if(DayDiff >= days) {
NextValue <- df[x,2]
PercentChange = (NextValue - StartValue)/NextValue
if(PercentChange >= growth) {
ReturnDF[(nrow(ReturnDF)+1),] <- list(StartDate, NextDate, PercentChange)
}
break
}
}
}
return(ReturnDF)
}
subDF <- Mydf[which(Mydf$Category=='A'), ]
subDF$Category <- NULL # Nuke the category column from the subsetting DF. It's not relevant for this.
X <- GetIncreasesWithinRange(subDF, 0.5, 4)
print(X)
哪个输出
StartDate EndDate Growth
1 2015-01-01 2015-01-05 0.8780488
2 2015-01-02 2015-01-06 0.8666667
3 2015-01-03 2015-01-07 0.8586957