কেন `ভ্যাপ্লি` pp স্যাপ্লি` এর চেয়ে নিরাপদ?


84

নথি বলছে

vapplyঅনুরূপ sapply, তবে এর একটি পূর্বনির্ধারিত ধরণের রিটার্ন মান রয়েছে, তাই এটি ব্যবহার করা নিরাপদ [...] হতে পারে।

আপনি কেন দয়া করে এটি সাধারণত নিরাপদ, সম্ভবত উদাহরণ সরবরাহ করে তা বিস্তারিতভাবে বর্ণনা করতে পারেন?


PS: আমি উত্তর জানি এবং আমি ইতিমধ্যে এড়ানো ঝোঁক sapply। আমি কেবল ইচ্ছুক যে এসও-তে এখানে একটি দুর্দান্ত উত্তর ছিল যাতে আমি আমার সহকর্মীদের এটিতে নির্দেশ করতে পারি। দয়া করে, কোনও "ম্যানুয়াল পড়বেন না" উত্তর।


4
কোডটি কম अस्पष्ट এবং আরও শক্তিশালী করে তোলে এটি আরও অনুমানযোগ্য। বিশেষত বড় প্রকল্পগুলিতে, একটি বৃহত প্যাকেজ বলুন, এটি প্রাসঙ্গিক।
পল হিমস্ট্র্রা

4
FUN.VALUE এর জন্য ভ্যাপলি ম্যানুয়াল উদাহরণগুলি অত্যন্ত জটিল এবং নীলকুঠকপূর্ণ ব্যবহারকারীদের জন্য ভয় দেখানোর।
jsta

উত্তর:


73

যেমনটি ইতিমধ্যে উল্লেখ করা হয়েছে, vapplyদুটি কাজ করে:

  • সামান্য গতির উন্নতি
  • সীমিত ফেরতের ধরণের চেক সরবরাহ করে ধারাবাহিকতা উন্নত করে।

দ্বিতীয় পয়েন্টটি হ'ল বৃহত্তর সুবিধা, কারণ এটি হওয়ার আগে ত্রুটিগুলি ধরতে সহায়তা করে এবং আরও দৃ code় কোডের দিকে নিয়ে যায়। এই রিটার্ন ভ্যালু চেকিংটি পৃথকভাবে sapplyঅনুসরণ করে stopifnotএটি ব্যবহার করে নিশ্চিত করা যায় যে রিটার্নের মানগুলি আপনার প্রত্যাশার সাথে সামঞ্জস্যপূর্ণ, তবে vapplyএটি কিছুটা সহজ (যদি আরও সীমাবদ্ধ থাকে, যেহেতু কাস্টম ত্রুটি পরীক্ষা করার কোডটি সীমানার মধ্যে মানগুলি পরীক্ষা করতে পারে ইত্যাদি ইত্যাদি) make )।

vapplyআপনার ফলাফলটি নিশ্চিত করার একটি উদাহরণ এখানে প্রত্যাশার মতো। এটি পিডিএফ স্ক্র্যাপ করার সময় আমি যেখানে কাজ করছিলাম তার সমান্তরাল কিছু, যেখানে findDএটি ব্যবহার করবেকাঁচা টেক্সট ডেটাতে একটি প্যাটার্নটি মেলে (যেমন আমার splitসত্তা অনুসারে একটি তালিকা ছিল এবং প্রতিটি সত্তার মধ্যে ঠিকানা মেলে একটি রেজেক্স ছিল Occ মাঝে মাঝে পিডিএফটি আউট-অর্ডারে রূপান্তরিত হয়ে যায় এবং সেখানে দুটি ঠিকানা থাকত সত্তা, যা খারাপ লাগায়)।

> input1 <- list( letters[1:5], letters[3:12], letters[c(5,2,4,7,1)] )
> input2 <- list( letters[1:5], letters[3:12], letters[c(2,5,4,7,15,4)] )
> findD <- function(x) x[x=="d"]
> sapply(input1, findD )
[1] "d" "d" "d"
> sapply(input2, findD )
[[1]]
[1] "d"

[[2]]
[1] "d"

[[3]]
[1] "d" "d"

> vapply(input1, findD, "" )
[1] "d" "d" "d"
> vapply(input2, findD, "" )
Error in vapply(input2, findD, "") : values must be length 1,
 but FUN(X[[3]]) result is length 2

আমি যেমন আমার ছাত্রদের বলি, প্রোগ্রামার হওয়ার অংশটি আপনার মানসিকতাকে "ত্রুটিগুলি বিরক্তিকর" থেকে "ত্রুটিগুলি আমার বন্ধু" হিসাবে পরিবর্তন করছে।

শূন্য দৈর্ঘ্যের ইনপুটগুলির
একটি সম্পর্কিত বিষয় হ'ল ইনপুট দৈর্ঘ্য যদি শূন্য sapplyহয় তবে ইনপুট প্রকার নির্বিশেষে সর্বদা একটি খালি তালিকা ফিরে আসবে। তুলনা করা:

sapply(1:5, identity)
## [1] 1 2 3 4 5
sapply(integer(), identity)
## list()    
vapply(1:5, identity)
## [1] 1 2 3 4 5
vapply(integer(), identity)
## integer(0)

এর সাথে vapply, আপনার একটি নির্দিষ্ট ধরণের আউটপুট থাকার গ্যারান্টি রয়েছে, সুতরাং আপনাকে শূন্য দৈর্ঘ্যের ইনপুটগুলির জন্য অতিরিক্ত চেক লেখার দরকার নেই।

বেঞ্চমার্ক

vapply কিছুটা দ্রুত হতে পারে কারণ ফলাফলটি আশা করা উচিত এটির ফর্ম্যাটটি ইতিমধ্যে জানে।

input1.long <- rep(input1,10000)

library(microbenchmark)
m <- microbenchmark(
  sapply(input1.long, findD ),
  vapply(input1.long, findD, "" )
)
library(ggplot2)
library(taRifx) # autoplot.microbenchmark is moving to the microbenchmark package in the next release so this should be unnecessary soon
autoplot(m)

অটোপ্লট


15

এতে জড়িত অতিরিক্ত কী স্ট্রোক vapplyআপনার ডিবাগিংয়ের পরে বিভ্রান্তিকর ফলাফলগুলি সাশ্রয় করতে পারে। আপনি যে ফাংশনটি কল করছেন তা যদি বিভিন্ন ডেটাটাইপগুলি ফিরিয়ে vapplyদিতে পারে তবে অবশ্যই ব্যবহার করা উচিত।

একটা উদাহরণ মনে আসে যে হবে sqlQueryRODBCপ্যাকেজ। যদি কোনও জিজ্ঞাসা চালাতে কোনও ত্রুটি হয় তবে এই ফাংশনটি characterবার্তা সহ একটি ভেক্টরকে ফেরত দেয়। সুতরাং, উদাহরণস্বরূপ, বলুন যে আপনি টেবিলের নামগুলির একটি ভেক্টরটির সাথে পুনরাবৃত্তি করতে চেষ্টা করছেন tnamesএবং প্রতিটি সারণির সংখ্যাসূচক কলাম 'নামকোল' থেকে সর্বাধিক মানটি নির্বাচন করুন:

sapply(tnames, 
   function(tname) sqlQuery(cnxn, paste("SELECT MAX(NumCol) FROM", tname))[[1]])

যদি সমস্ত টেবিলের নাম বৈধ হয় তবে এর ফলে numericভেক্টর আসতে পারে। তবে যদি কোনও টেবিলের নাম ডাটাবেসে পরিবর্তন ঘটে এবং ক্যোয়ারী ব্যর্থ হয়, ফলাফলগুলি মোডে জোর করে চলেছে character। তবে এর vapplyসাথে ব্যবহার করা FUN.VALUE=numeric(1)এখানে ত্রুটিটি থামিয়ে দেবে এবং এটিকে কোথাও লাইন থেকে পপ করতে বাধা দেবে --- বা আরও খারাপ, কিছু নয়।


13

আপনি যদি সবসময় চান যে আপনার ফলাফলটি বিশেষভাবে কিছু হোক ... যেমন লজিকাল ভেক্টর। vapplyএটি ঘটে তা নিশ্চিত sapplyকরে তবে অগত্যা তা করে না।

a<-vapply(NULL, is.factor, FUN.VALUE=logical(1))
b<-sapply(NULL, is.factor)

is.logical(a)
is.logical(b)

4
আমি মনে করি সর্বাধিক সুস্পষ্ট কাজটি logical(1)এই ক্ষেত্রে, কারণ ফলস দেখে মনে হচ্ছে এটি কোনও ধরণের নির্দিষ্টকরণের পরিবর্তে "অফ" করার বিকল্প নির্ধারণ করে
উড়ন্ত ভেড়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.