我的问题如下。
说,对于数据集中的每个度量,我都有一个带有标识符“ A”的data.frame。另外,我有一个时间值(数字)和一个差异值(数字)。数据集看起来像这样:
df <- data.frame(Identifier = c("A","A","A","A","A","A","A","A"),
Time_between = c(15, 25, 5, 6, 17, 9, 28, 3),
Difference = c(3, 15, -8, 7, 16, 29, 2, 0))
#> Identifier Time_between Difference
#> 1 A 15 3
#> 2 A 25 15
#> 3 A 5 -8
#> 4 A 6 7
#> 5 A 17 16
#> 6 A 9 29
#> 7 A 28 2
#> 8 A 3 0
我想实现的是Time_between的累积值,但仅使用与差> 0有关的值。因此,差的第三个值-8应该得出累积值中未使用的值“ 5”。
我尝试编写一个函数,其中:
sum_if<- function(h,i){
sum(h[i>0])}
但是综合使用此功能会给我多个错误消息:
trial<-aggregate(df$time_between, by=df["Identifier"],
FUN=function(h,i) sum_if(df$time_between, df$diff))
Error in sum(h[i > 0]) : invalid 'type' (character) of argument
我的数据框非常大(> 100万个观测值x 25个变量),所以这是我使用的数据的简化版本。
另外,我想得到一个小于0的值,求和重新开始。
尝试了一些建议的答案后的其他信息。
我遇到了一些问题。使用plyr讨论第一个选项确实可以在我在本文中创建的数据集中使用,但是在将其应用到我现有的较大数据集中时会遇到问题。也许有些现实:
df <- data.frame(Identifier = c("A","A","B","C","C","C","D","E"),
Time_between = c(NA, 25, NA, NA, 17, 9, NA, NA),
Difference = c(NA, 15, NA, NA, 16, -239, NA, NA))
NA适用于信息,因此不应忽略。例如: 如果标识符A具有一个NA和25(“间隔时间”),则表示第二个处方的时间为第一个之后的25天。举例来说,如果第一次是在时间点10进行规定,而第二次是在时间点25,则相差15。
我尝试使用以下方法做第一个选择:
df_trial<- df_trial %>% group_by(Studienummer) %>%
mutate(condsumPlyr=cumsum(df_trial$time_between)*(df_trial$diff_A>0)) %>%
ungroup()
这导致错误:
错误:mutate()
输入condsumPlyr
出现问题。
x输入condsumPlyr
无法回收为大小1。
i输入condsumPlyr
为cumsum(df_trial$time_between) * (df_trial$diff_A > 0)
。
i输入condsumPlyr
的大小必须为1,而不是10576。
i错误发生在第1组:标识符= 59。
我尝试的第二件事是使用:
df_trial[,(consumDT:= cumsum(time_between*(diff_A>0))), by=Identifier]
不起作用的错误: 未使用的参数(by =标识符)
最后,使用以下代码:
df_trial$cumsumBR <- sapply(split(df_trial, df_trial$Studienummer),
function(df_trial)cumsum(df_trial$time_between * (df_trial$diff_A > 0)))
发生以下错误: $<-.data.frame
(*tmp*
中的错误,cumsumBR,值= list(59
= NA_real_,:
替换项有3106行,数据项有10576
我不确定哪个选项能满足我的首选结果,但是它们似乎都不起作用。
旁注:在我给出的“简单”数据集上,确实获得了预期的结果。谢谢!
答案 0 :(得分:1)
如果要保留结构,可以使用布尔值来模拟ifelse
(比ifelse
更快),并使用cumsum
来获取累积和。使用dplyr
,我们可以得到可读的表达式来执行计算。
library(dplyr)
library(tidyr)
df <- df %>%
group_by(Identifier) %>%
mutate(condsumdPlyr = cumsum(Time_between * (Difference > 0))) %>%
ungroup()
在data.table
或disk.frame
中,我们将使用它们的标准符号
library(data.table)
setDT(df) #change df to data.table
df[, consumDT := cumsum(Time_between * ( Difference > 0 ) ), by = Identifier]
# Alternative: df[Difference > 0, consumDT := cumsum(Time_between), by = Identifier]
setDF(df) #Only to change it back to a data.frame
在基数R
中,我们想使用aggregate
,但是由于我们需要使用多列,因此使用split
和sapply
更为简单(类似于tapply
如何用于数组)
df$consumBase <- sapply(split(df, df$Identifier), function(df)cumsum(df$Time_between * (df$Difference > 0)))
现在,如果您坚决使用aggregate
,则生命将变得更加复杂,因为它打算用于单列聚合。我们可以使用subset
参数来解决问题,但这会删除正确的索引,并且很难将结果与原始data.frame
合并
condDf <- aggregate(Time_between ~ Identifier, data = df, FUN = cumsum, subset = df$Difference > 0)
condDf <- data.frame(Identifier = rep(condDf$Identifier, lengths(condDf$Time_between)), condsumAggregate = unlist(condDf$Time_between))
Ofc。如果我们length(unique(df$Identifier))
为1,这将变得更加简单,因为我们不需要对数据进行分组。
免责声明:如果没有数据,我将无法正确测试其拼写错误