هل يمكنك استخدام وظيفة Lapply () لتغيير قيمة الإدخال؟

StackOverflow https://stackoverflow.com/questions/1559724

  •  21-09-2019
  •  | 
  •  

سؤال

كنت أتساءل عما إذا كان من الممكن استخدام وظيفة Lapply () لتغيير قيمة المدخلات ، على غرار:

a1<-runif(100)
a2<-function(i){
a1[i]<-a1[i-1]*a1[i];a1[i]
}
a3<-lapply(2:100,a2)

أنا أبحث عن شيء أقرب إلى حلقة () ، ولكن باستخدام البنية التحتية Lapply (). لم أتمكن من الحصول على Rapply () للقيام بذلك.

والسبب هو أن وظيفة A2 "الحقيقية" هي وظيفة صعبة لا تحتاج إلا إلى تقييم إذا تلبية قيمة A1 [I-1] بعض المعايير.

إعادة الصياغة: لذلك أحاول استبدال FOR () في الكود أدناه بواسطة lapply ()-اكتب الشيء:

    a1<-runif(100)
    a2<-function(i, a1){
        a1[i]<-a1[i-1]*2
        a1[i]
    }
    a3<-as.numeric(lapply(2:100, a2, a1=a1))
#compare the output of a3 with that of a1 after the recursive loop
    a2<-a1 #saved for comparison
    for(i in 2:length(a1)){
        a1[i]<-a1[i-1]*2
    }
cbind(a1[2:100],a3)
#actually this is would be like writting a lapply() version of the cumprod() function
cbind(a1,cumprod(a2))

نصحت القائمة البريدية R النظر إلى وظيفة تقليل () .... كما في:

a1<-runif(100)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
cadd(a1)

الذي يعطي نفس النتيجة مثل Cumprod (A1) ... ولكنه أبطأ من الحلقة:

a1<-runif(100000)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
looop<-function(a1){
j<-length(a1)
    for(i in 2:j){
        a1[i]<-a1[i-1]*a1[i]
    }
a1
}

> system.time(cadd(a1))
   user  system elapsed 
  1.344   0.004   1.353 
> system.time(cumprod(a1))
   user  system elapsed 
  0.004   0.000   0.002 
> system.time(loop(a1))
   user  system elapsed 
  0.772   0.000   0.775 
> 

اي فكرة ؟

هل كانت مفيدة؟

المحلول

تعديل: بعد التوضيح الخاص بك: لا ، لا أعتقد أنه يمكنك استخدام وظيفة تطبيق للقيام بشيء متكرر مثل هذا. النقطة الأساسية من وظيفة التطبيق هي أنه ينطبق عبر المتجه/المصفوفة في نفس الوقت.

قد ترغب أيضًا في ذلك انظر إلى هذا السؤال ذي الصلة على Stackoverflow.

إجابتي القديمة:

جرب هذا:

a1<-runif(100)
a2<-function(i, a1){
    a1[i]<-a1[i-1]*a1[i]
    a1[i]
}
a3 <- as.numeric(lapply(2:100, a2, a1=a1))

على عكس أ for حلقة ، تحتاج إلى المرور في إشارة إلى أي شيء تحتاجه داخل lapply. العودة هي أيضًا قائمة ، لذلك تحتاج إلى إرجاعها إلى أي شكل تريده.

قد ترغب أيضًا في إلقاء نظرة على حزمة PLYR لطرق سهلة للقيام بهذا النوع من الأشياء.

علاوة على ذلك ، يمكنك القيام بعملك بدون حلقة:

a3 <- a1[-length(a1)] * a1[-1]

بمعنى آخر ، هذه العبارات مكافئة تمامًا:

> all((a1[-length(a1)] * a1[-1]) == as.numeric(lapply(2:100, a2, a1=a1)))
[1] TRUE

لكن الإصدار الأول هو الأفضل لأنه لا يحتوي على تكرارات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top