【问题标题】:Insert rows in a dataframe based on a calculation根据计算在数据框中插入行
【发布时间】:2017-09-30 19:25:11
【问题描述】:

我对 R 很陌生,我正在尝试将在 Excel 中完成的计算复制到 R。
我有一个这样的数据框:

Component <- c("A", "B", "C")
Report_Time <- c(5781, 5781, 5781)
Interval <- c(700, 600, 800)
End_Time <- c(8281, 8281, 8281)
Start_Time <- c(800, 298, 780)
df <- data.frame(Component, Report_Time, Interval, End_Time, Start_Time)

打印出来后是这样的:

# Component Report_Time Interval    End_Time    Start_Time
#1    A         5781        700         8281        800
#2    B         5781        600         8281        298
#3    C         5781        800         8281        780

对于每个组件,我想填充一个计算列“Interval_Time”,它是 First 的 Start Time + Report_Time 的总和,然后如果它小于 End_Time,则插入一个带有 Interval_Time 总和的行(最后一个总和) + 间隔。重复插入,直到 Interval 时间的总和小于 End_Time。

# Component Report_Time Interval    End_Time    Start_Time  Interval_Time
#1   A       5781       700             8281        800         6581
#2   A       5781       700             8281        800         7281
#3   A       5781       700             8281        800         7981
#4   B       5781       1000            8281        298         6079        
#5   B       5781       1000            8281        298         7079
#6   B       5781       1000            8281        298         8079
#7   C       5781       1200            8281        780         6561
#8   C       5781       1200            8281        780         7761

我一直在尝试在 for 循环中使用 if 来实现这一点。但没有成功。

【问题讨论】:

  • 你不是说“重复插入直到间隔时间的总和大于End_Time”吗? “End_T2ime”看起来像是一个错字,当总和更大时您想停止。

标签: r dataframe rep


【解决方案1】:

data.table:

Component <- c("A", "B", "C")
Report_Time <- c(5781, 5781, 5781)
Interval <- c(700, 1000, 1200)
End_Time <- c(8281, 8281, 8281)
Start_Time <- c(800, 298, 780)
df <- data.frame(Component, Report_Time, Interval, End_Time, Start_Time)

library(data.table)
setDT(df)
df<-df[rep(1:.N,ceiling((End_Time-Start_Time-Report_Time)/Interval))]
df[,Interval_Time:=ifelse(.I==1,Start_Time+Report_Time,Start_Time+cumsum(Interval)+Report_Time-Interval),by=.(Component)]

df
Component Report_Time Interval End_Time Start_Time Interval_Time
1:         A        5781      700     8281        800          6581
2:         A        5781      700     8281        800          7281
3:         A        5781      700     8281        800          7981
4:         B        5781     1000     8281        298          6079
5:         B        5781     1000     8281        298          7079
6:         B        5781     1000     8281        298          8079
7:         C        5781     1200     8281        780          6561
8:         C        5781     1200     8281        780          7761

【讨论】:

  • 感谢@fasttouch
【解决方案2】:

请检查此部分解决方案是否对您有用。如果您想继续添加直到间隔时间小于 End_T2ime,那么您还必须复制其他行。

Component <- c("A", "B", "C")
Report_Time <- c(5781, 5781, 5781)
Interval <- c(700, 600, 800)
End_Time <- c(8281, 8281, 8281)
Start_Time <- c(800, 298, 780)
df <- data.frame(Component, Report_Time, Interval, End_Time, Start_Time)

df$Interval_time[1]=df[1,2]+df[1,5]
for(i in 2:nrow(df))
{

  if((df[i,2]+df[i,5]) < df[i,4])
     df$Interval_time[i]=df$Interval_time[i-1]+df[i,3]
  else
    df$Interval_time[i]=df[i,2]+df[i,5]

}

【讨论】:

    【解决方案3】:

    不像@Erden Akkas 的那样优雅,但因为我一直在研究它;)

    注意,此方法的工作原理是假设原始数据帧仅作为每个组件的一个观察值。

    df$value <- df$Start_Time + df$Report_Time
    
    for (i in 1:nrow(df))
    {
      t <- df[i,]
      val <- t$value
      repeat {
        val <- val + t$Interval
        if (val > t$End_Time) {break}
        dftmp <- df[i,]
        dftmp$value <- val
        # Insert new Record
        df <- rbind(df, dftmp) 
    
       }
     }
     df[with(df, order(Component)), ]
    

    但这显然在本质上更具程序性,就像 @Erden Akkas 的唯一一个带有数据表库的东西......但无论如何它都能完成工作......

       Component Report_Time Interval End_Time Start_Time value
    1          A        5781      700     8281        800  6581
    4          A        5781      700     8281        800  7281
    5          A        5781      700     8281        800  7981
    2          B        5781      600     8281        298  6079
    21         B        5781      600     8281        298  6679
    22         B        5781      600     8281        298  7279
    23         B        5781      600     8281        298  7879
    3          C        5781      800     8281        780  6561
    31         C        5781      800     8281        780  7361
    32         C        5781      800     8281        780  8161
    

    【讨论】:

      猜你喜欢
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多