كيفية استخدام acast (reshape2) ضمن وظيفة في r؟
-
04-10-2019 - |
سؤال
حاولت استخدام acast
من reshape2
ضمن وظيفة مكتوبة ذاتيا ، ولكن كانت المشكلة التي لم تجد ACAST البيانات التي أرسلها إليها.
ها هي بياناتي:
library("reshape2")
x <- data.frame(1:3, rnorm(3), rnorm(3), rnorm(3))
colnames(x) <- c("id", "var1", "var2", "var3")
y <-melt(x, id = "id", measure = c("var1", "var2", "var3"))
y
ثم يبدو هكذا:
id variable value
1 1 var1 0.1560812
2 2 var1 1.0343844
3 3 var1 -1.4157728
4 1 var2 0.8808935
5 2 var2 0.1719239
6 3 var2 0.6723758
7 1 var3 -0.7589631
8 2 var3 1.1325995
9 3 var3 -1.5744876
الآن يمكنني إرجاعه عبر acast
:
> acast(y,y[,1] ~ y[,2])
var1 var2 var3
1 0.1560812 0.8808935 -0.7589631
2 1.0343844 0.1719239 1.1325995
3 -1.4157728 0.6723758 -1.5744876
ومع ذلك ، عند كتابة غلاف صغير acast
يجب أن تفعل الشيء نفسه ، أحصل على رسائل خطأ غبية:
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
out <- acast(dat, dat[,v1] ~ dat[,v2])
return(out)
}
wrap.acast(y)
Error in eval(expr, envir, enclos) : object 'dat' not found
من الواضح أن المشكلة مرتبطة بشيء مثل البيئات والمتغيرات العالمية/المحلية. لأنه يعطي رسائل خطأ أخرى بعد الإعلان dat
في البيئة العالمية (أي ، v1
و v2
لم يتم العثور عليها طالما أنها ليست عالمية).
أرغب في استخدام Resahpe (وخاصة Acast) ضمن وظيفة دون ضرورة إعلان المتغيرات خارج الوظيفة. ما هي الحيلة؟
شكرًا.
المحلول
بدلاً من استخدام مواصفات الصيغة ، استخدم مواصفات الأحرف:
acast(y, list(names(y)[1], names(y)[2]))
نصائح أخرى
إحدى المشكلات هي أنك تسيء إلى تدوين الصيغة في R. لا يجب أن تفعل أشياء مثل
> acast(y, y[,1] ~ y[,2])
var1 var2 var3
1 2.1726117 0.6107264 0.291446236
2 0.4755095 -0.9340976 -0.443291873
3 -0.7099464 -1.2536334 0.001105352
نظرًا لأن البتات "Y" زائدة عن الحاجة إذا تم توفير كائن بيانات. إذا كنت تشير إلى متغيرات Y بالاسم مباشرة في الصيغة ، فإن الأمور تعمل بشكل جيد
> acast(y, id ~ variable)
var1 var2 var3
1 2.1726117 0.6107264 0.291446236
2 0.4755095 -0.9340976 -0.443291873
3 -0.7099464 -1.2536334 0.001105352
والرمز أكثر قابلية للقراءة في هذا الإصدار الثاني.
لفعل ما تريد باستخدام acast
سوف يتضمن الغلاف توليد الصيغة الصحيحة باستخدام names
, ، كما يشير Joris ، وحل Hadley أبسط بكثير. لذا فإن وجهة نظري هي أن تراقب كيفية استخدام مواصفات الصيغة في R. ، ستوفر لنفسك الكثير من المتاعب على المدى الطويل (على الرغم من عدم هذه المشكلة بالتحديد) إذا كنت تستخدم الصيغ بشكل صحيح.
التصحيح: المشكلة ليست أنها لا تجد DAT ، ولكنها لا تجد DAT [، V1] و DAT [، V2] في الصيغة المحددة. يأخذ Acast وسيطة من صيغة النوع ، ويتم تقييمها في بيئة مؤقتة تم إنشاؤها حول إطار البيانات الخاص بك. ضمن تلك البيئة ، لا يجد كائن "DAT" عندما يتم لف الوظيفة داخل أخرى.
أنا لا أتابع تمامًا كيف يعمل هذا في العالم ولا يلفه عند لفه ، ولكن إذا قمت بإطعام صيغة ، فإنها تعمل ضمن وظيفة أيضًا.
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
x1 <- names(dat)[v1]
x2 <- names(dat)[v2]
form <- as.formula(paste(x1,"~",x2))
out <- acast(dat,form)
return(out)
}
باستخدام بيانات لعبتك:
> wrap.acast(y)
var1 var2 var3
1 0.04095337 0.4044572 -0.4532233
2 1.23905358 1.2493187 0.7083557
3 0.72798307 0.7868746 1.7144811
لقد وجدت طريقة غير متوفرة لحل المشكلة باستخدام المهام الفائقة (<<-
).
تغيير الوظيفة إلى ما يلي هل المهمة. لكنها قبيحة للغاية لأنها تخلق متغيرات عالمية تبقى.
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
dat <<- dat
v1 <<- v1
v2 <<- v2
out <- acast(dat, dat[,v1] ~ dat[,v2])
return(out)
}
ما زلت مهتمًا جدًا بحلول أخرى (أقل انسداد).
قبل تشغيل الوظيفة:
> ls()
[1] "wrap.acast" "x" "y"
بعد تشغيل الوظيفة:
> ls()
[1] "dat" "v1" "v2" "wrap.acast" "x"
[6] "y"