2017-05-03 13 views
5

Tôi khá mới cho R và tôi đang cố gắng để sao chép một tính toán thực hiện trong Excel để R.
Tôi có một khung dữ liệu như thế này:Chèn hàng trong một dataframe dựa trên một tính

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) 

Khi in nó trông như thế này:

# 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 

đối với mỗi thành phần, tôi muốn để cư một cột tính "Interval_Time", mà là tổng của Start Time + Report_Time cho Thứ nhất, sau đó nếu nó là ít hơn END_TIME chèn một hàng với tổng của Interval_Time (Tổng cuối) + Interv al. Lặp lại chèn cho đến khi tổng trong khoảng thời gian Khoảng thời gian nhỏ hơn 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 

Tôi đã cố gắng đạt được điều này nếu trong vòng lặp for .. nhưng chưa thành công.

+0

Đừng bạn có ý nghĩa "Lặp lại chèn cho đến khi tổng trong khoảng thời gian Khoảng thời gian là ** lớn hơn ** ** End_Time **"? "End_T2ime" trông giống như lỗi đánh máy và bạn muốn dừng khi tổng lớn hơn. – steveb

Trả lời

3

Với 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 
+0

Giải pháp thanh lịch @Erdem Akkas ... – Umberto

+0

Cảm ơn @fasttouch –

0

Vui lòng kiểm tra xem giải pháp một phần này có hữu ích cho bạn hay không. Nếu bạn muốn tiếp tục thêm vào cho đến khi khoảng thời gian ít hơn End_T2ime thì bạn phải lặp lại các hàng khác.

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] 

} 
0

Không thanh lịch như một bằng @Erden Akkas, nhưng kể từ khi tôi đã làm việc trên nó anyway;)

NB phương pháp này trình giả định dữ liệu gốc khung như chỉ một quan sát cho mỗi thành phần.

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)), ] 

Nhưng điều này rõ ràng là thủ tục hơn trong tự nhiên như ony bởi @Erden Akkas với thư viện bảng dữ liệu ... Nhưng nó được công việc làm dù sao đi nữa ...

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 
Các vấn đề liên quan