تحديد النمط في R ، وحساب القيم وتعيينها وفقًا لذلك

3

أنا جديد في R لذا قد يكون هذا السؤال أساسيًا. هناك عمود في بياناتي على النحو 4 4 4 4 7 7 7 13 13 13 13 13 13 13 4 4 7 7 7 13 13 13 13 13 13 13 13 4 4 .....

تعتبر دورة واحدة من 4 ... 7 ... 13 ... بمثابة دورة كاملة واحدة ، وسأعين لها رقم تشغيل (1 ، 2 ، 3 ...) لكل جولة.

عدد مرات تكرار كل قيمة (4 ، 7 ، 13) غير ثابت ، كما لم يتم إصلاح العدد الإجمالي للصفوف في التشغيل. العدد الإجمالي للركض غير معروف (ولكن يتراوح عادة من 60-90). ترتيب (4 ، 7 ، 13) ثابت.

لقد أرفقت شفرتي الحالية هنا. يعمل بشكل جيد ، ولكنه يستغرق دقيقة أو دقيقتين عندما يكون هناك بضعة ملايين من صفوف البيانات. أنا على دراية بأن زراعة النواقل في حلقة for لا يوصى بها حقًا في R ، لذلك أود أن أسأل ما إذا كان لدى أي شخص حل أكثر أناقة لهذا.

يمكن إنشاء بيانات نموذجية باستخدام الكود أدناه ، كما يمكن إنشاء المخرجات المطلوبة باستخدام رمز عينة أدناه.

#Generates sample data
df <- data.frame(Temp = c(sample(50:250, 30)), Pres = c(sample(500:1000, 30)), 
             Message = c(rep(4, 3), rep(7, 2), rep(13, 6), rep(4, 4), rep(7, 1), rep(13, 7), rep(4, 3), rep(7, 4)))

الحل الحالي

prev_val = 0
Rcount = 1
Run_Count = c()
for (val in df$Message)
{
  delta = prev_val - val
  if((delta == 9))
  Rcount = Rcount + 1
  prev_val = val
  Run_Count = append(Run_Count, Rcount)
}
df$Run = Run_Count

الإخراج المطلوب:

226 704 4  1
138 709 4  1
136 684 4  1 
 57 817 7  1
187 927 7  1
190 780 13 1
152 825 13 1
126 766 13 1
202 855 13 1
214 757 13 1
172 922 13 1
 50 975 4  2
159 712 4  2
212 802 4  2
181 777 4  2
102 933 7  2
165 753 13 2
 67 962 13 2
119 631 13 2

سيتم تقسيم إطار البيانات لاحقًا بواسطة رقم التشغيل ، ولكن بعد تصنيفه وفقًا للقيمة ، أي

... 4 1 
... 4 1 
... 4 1 
... 4 1 
... 4 2 
... 4 2 
... 4 2 
... 4 3
.....

2 الاجابة

2
افضل جواب

لست متأكدا مما إذا كان هذا تحسنا ، لكنه يستخدم rle وظيفة ترميز طول التشغيل لتحديد طول كل تكرار في كل تشغيل.

df <- data.frame(Temp = c(sample(50:250, 30)), Pres = c(sample(500:1000, 30)), 
                 Message = c(rep(4, 3), rep(7, 2), rep(13, 6), rep(4, 4), rep(7, 1), rep(13, 7), rep(4, 3), rep(7, 4)))

rleout<-rle(df$Message)
#find the length of the runs and create the numbering
runcounts<-ceiling(length(rleout$lengths)/3)
runs<-rep(1:runcounts, each=3)    

#need to trim the length of run numbers for cases where there is not a  
#   full sequence, as in the test case.
rleout$values<-runs[1:length(rleout$lengths)]

#create the new column
df$out<-inverse.rle(rleout)

أنا متأكد من أن شخصًا ما يمكن أن يأتي ويعرض طريقة أفضل وأسرع باستخدام جداول البيانات.

:مؤلف
2
افضل جواب

استخدم بسهولة:

df$runID <- cumsum(c(-1,diff(df$Message)) < 0)

#    Temp Pres Message runID
# 1   174  910       4     1
# 2   181  612       4     1
# 3   208  645       4     1
# 4    89  601       7     1
# 5   172  812       7     1
# 6   213  672      13     1
# 7   137  848      13     1
# 8   153  833      13     1
# 9   127  591      13     1
# 10  243  907      13     1
# 11  146  599      13     1
# 12  151  567       4     2
# 13  139  855       4     2
# 14  147  793       4     2
# 15  227  533       4     2
# 16  241  959       7     2
# 17  206  948      13     2
# 18  236  875      13     2
# 19  133  537      13     2
# 20   70  688      13     2
# 21  218  528      13     2
# 22  244  927      13     2
# 23  161  697      13     2
# 24  177  572       4     3
# 25  179  911       4     3
# 26  192  559       4     3
# 27   60  771       7     3
# 28  245  682       7     3
# 29  196  614       7     3
# 30  171  536       7     3
:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام