স্ট্রিং হিসাবে দেওয়া এক্সপ্রেশনকে মূল্যায়ন করুন


283

আমি জানতে আগ্রহী যে eval()কোনও স্ট্রিং দ্বারা সরবরাহ করা গণনা সম্পাদনের জন্য আর এর ফাংশনটি ব্যবহার করতে পারে কিনা I'm

এটি একটি সাধারণ ঘটনা:

eval("5+5")

তবে, 10 এর পরিবর্তে আমি পেয়েছি:

[1] "5+5"

কোন সমাধান?


6
সমস্ত উত্তর সত্ত্বেও কীভাবে এটি পার্সের মাধ্যমে সমাধান করা যায় তা দেখানো হচ্ছে ... কেন আপনার ভাষার অক্ষর একটি চরিত্রে সংরক্ষণ করা দরকার string? মার্টিন মাচলারের উত্তরটি আরও অনেক বেশি উপায়ে প্রাপ্য হওয়া উচিত।
পেটর মাতৌসু

7
আপনাকে @ পেটারমাতৌসু ধন্যবাদ। হ্যাঁ, এখন এসও-তে কীভাবে ভুল তথ্য ছড়িয়ে পড়েছে তা দেখে আমি হতবাক হয়েছি .. লোকেরা eval(parse(text = *)) জাল সমাধানগুলি সমর্থন করে।
মার্টিন মাচলার

2
আমি ফর্মের স্ক্রিপ্টগুলি চালাতে চাই: QQ = c('11','12','13','21','22','23')যেমন: কিউকিউ = সি (..., 'আইজ', ..) সাথে আই, জে একটি রেঞ্জের পরিবর্তিত হতে পারে যা রান থেকে রান পর্যন্ত পরিবর্তিত হতে পারে। এটি এবং অনুরূপ উদাহরণগুলির জন্য, আমি স্ক্রিপ্টটি লিখতে পারি paste( "QQ = c('", paste(rep(1:2,each=3),1:3, sep="", collapse="','"), "')",sep="")এবং অপশনটি স্ক্রিপ্ট eval(parse(text=...))অনুসারে কর্ম পরিবেশে ভেক্টর কিউকিউ তৈরি করে। "টেক্সট = ..." দিয়ে না থাকলে এটি করার উপযুক্ত আর কোডার উপায় কী হবে?
ভিক্টরজুরকোভস্কি

উত্তর:


418

eval()ফাংশন একটি অভিব্যক্তি মূল্যায়ণ কিন্তু "5+5"একটি স্ট্রিং, না একটি অভিব্যক্তি। ব্যবহার করুন parse()সঙ্গে text=<string>একটি অভিব্যক্তি মধ্যে স্ট্রিং পরিবর্তন করতে:

> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"

কল করা eval()অনেকগুলি আচরণের জন্য আহ্বান জানায়, কিছু অবিলম্বে সুস্পষ্ট হয় না:

> class(eval(parse(text="5+5")))
[1] "numeric"
> class(eval(parse(text="gray")))
[1] "function"
> class(eval(parse(text="blue")))
Error in eval(expr, envir, enclos) : object 'blue' not found

ট্রাইচ্যাচও দেখুন ।


27
শেন নীচে যেমন নোট করেছেন, "আপনাকে ইনপুটটি পাঠ্য তা নির্দিষ্ট করা দরকার, কারণ পার্স ডিফল্টরূপে কোনও ফাইলের প্রত্যাশা করে"
প্যাট্রিকটি

1
ইভাল (পার্স) ব্যবহারের পার্শ্ব প্রতিক্রিয়াগুলি নির্দিষ্ট করা উচিত। উদাহরণস্বরূপ, যদি আপনার "ডেভিড" সমান পূর্ব-সংজ্ঞায়িত ভেরিয়েবল নাম থাকে এবং আপনি eval (পার্স (পাঠ্য = "নাম") == "আলেকজান্ডার" ব্যবহার করে পুনরায় সাইন করেন, আপনি একটি ত্রুটি পাবেন কারণ eval এবং pars একটি ফিরিয়ে দেয় না আর অভিব্যক্তি মূল্যায়ন করা করতে পারেন।
ইয়েলো

1
@NelsonGon: Unevaluated এক্সপ্রেশান্স ব্যবহার করে নির্মিত quote(), bquote()অথবা আরো পরিশীলিত দ্বারা উপলব্ধ সরঞ্জাম rlangপ্যাকেজ।
আর্টেম সোকোলভ

@ আর্টেমসোকোলভ ধন্যবাদ, আমি কোনওভাবেই বিকল্পের সন্ধানে এই প্রশ্নে ফিরে আসছি। আমি দেখেছি rlangতবে আমার কাছে সবচেয়ে কাছের পাওয়া গেছে parse_exprযা কলগুলি ছিল যা parse_exprsঘুরে দেখা যায় parseএটি ব্যবহার এবং মোড়ানো সমান evalযা এখানে করা একই জিনিস বলে মনে হয়। সুবিধাটি ব্যবহারে কী হবে তা আমি নিশ্চিত নই rlang
নেলসনগন

1
@ নেলসনগন: এর সাথে rlangআপনি সরাসরি স্ট্রিং নয়, প্রকাশের সাথে কাজ করবেন। কোনও বিশ্লেষণমূলক পদক্ষেপের প্রয়োজন নেই। এর দুটি সুবিধা রয়েছে। 1. এক্সপ্রেশন ম্যানিপুলেশনগুলি সর্বদা বৈধ এক্সপ্রেশন তৈরি করে। স্ট্রিং ম্যানিপুলেশনগুলি কেবল বৈধ স্ট্রিং তৈরি করে। আপনি তাদের পার্স না করা পর্যন্ত সেগুলি বৈধ এক্সপ্রেশন কিনা তা আপনি জানতে পারবেন না। ২. substitute()স্ট্রিং ওয়ার্ল্ডে ফাংশনের শ্রেণির সাথে সমতুল্য কোনও কিছুই নেই , যা ফাংশন কলগুলি পরিচালনা করার জন্য আপনার দক্ষতার মারাত্মকভাবে সীমাবদ্ধ করে। এই গ্ল্যাম্প আবরণ বিবেচনা করুন । একটি স্ট্রিং সমতুল্য দেখতে কেমন হবে?
আর্টেম সোকলভ

100

আপনি parse()অক্ষরকে একটি এক্সপ্রেশন রূপান্তর করতে ফাংশনটি ব্যবহার করতে পারেন । আপনাকে নির্দিষ্ট করতে হবে যে ইনপুটটি পাঠ্য, কারণ পার্স ডিফল্টরূপে কোনও ফাইলের প্রত্যাশা করে:

eval(parse(text="5+5"))

7
> ভাগ্য :: ভাগ্য ("উত্তর পার্স হয়") উত্তরটি পার্স করা হলে () আপনার সাধারণত প্রশ্নটি পুনর্বিবেচনা করা উচিত। - টমাস লুমলে আর-সহায়তা (ফেব্রুয়ারী 2005)>
মার্টিন মাচলার

13
@ মার্টিনম্যাচলার এটি বিদ্রূপাত্মক, কারণ মূল আর প্যাকেজগুলি parseসর্বদা ব্যবহার করে! github.com/wch/r-source/…
জেনারোমা

49

দুঃখিত তবে আমি বুঝতে পারছি না কেন খুব বেশি লোক এমনকি একটি স্ট্রিং এমন কিছু যা মূল্যায়ন করতে পারে বলেও মনে করে। আপনার অবশ্যই আপনার মানসিকতা পরিবর্তন করতে হবে। একপাশে স্ট্রিং এবং অন্য দিকে এক্সপ্রেশন, কল, মূল্যায়নের মধ্যে সমস্ত সংযোগ ভুলে যান।

(সম্ভবত) কেবল সংযোগটিই এর মাধ্যমে parse(text = ....)এবং সমস্ত ভাল আর প্রোগ্রামারদের জানা উচিত যে এক্সপ্রেশন (বা কলগুলি) নির্মাণের এটি খুব কমই কার্যকর বা নিরাপদ উপায়। বরং আরো সম্পর্কে জানতে substitute(), quote(), এবং সম্ভবত ব্যবহারের ক্ষমতা do.call(substitute, ......)

fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
#    -- Thomas Lumley
#       R-help (February 2005)

ডিসেম্বর ২০১7: ঠিক আছে, এখানে একটি উদাহরণ দেওয়া হয়েছে (মন্তব্যগুলিতে, কোনও দুর্দান্ত বিন্যাস নেই):

q5 <- quote(5+5)
str(q5)
# language 5 + 5

e5 <- expression(5+5)
str(e5)
# expression(5 + 5)

এবং আপনি যদি আরও অভিজ্ঞ হন তবে আপনি এটি শিখবেন q5a"call" যেহেতু e5একটি হল "expression"যে, এবং এমনকি e5[[1]]অভিন্ন q5:

identical(q5, e5[[1]])
# [1] TRUE

4
আপনি একটি উদাহরণ দিতে পারেন? হতে পারে আপনি আমাদের কীভাবে কোনও r বস্তুতে 5 + 5 থেকে "ধরে" রাখতে পারেন, তারপরে এটির মূল্যায়ন করুন, একটি চরিত্রের পরিবর্তে কোট এবং বিকল্প ব্যবহার করুন (পার্স (পাঠ্য =)?
রিচার্ড ডিসালভো

3
আমি কিছুটা হারিয়ে যেতে পারি। আপনি কোন মুহুর্তে 10 পাবেন? না যে বিন্দু না?
নিক এস

@RichardDiSalvo: হ্যাঁ, q5 <- quote(5+5)উপরে হয় অভিব্যক্তি (আসলে "কল") 5+5এবং এটি একটি r- বস্তু, কিন্তু না একটি পংক্তি। আপনি যে কোনও সময় এটি মূল্যায়ন করতে পারেন। আবার: ব্যবহার, উদ্ধৃতি (), বিকল্প (), ... পরিবর্তে পার্স পার্স (পাঠ্য =।) এর চেয়ে কল এবং এক্সপ্রেশন সরাসরি এবং আরও দক্ষতার সাথে তৈরি করে। ব্যবহার eval()করা ভাল, ব্যবহারের parse(text=*)ক্ষেত্রে ত্রুটিযুক্ত প্রবণ এবং কখনও কখনও নির্মাণ কলগুলির তুলনায় এবং সেগুলি হেরফের করার পক্ষে বেশ অকার্যকর .. @ নিক এস: এটি eval(q5) বা eval(e5) আমাদের চলমান উদাহরণে
মার্টিন মার্চর

@ নিকস: 10 টি পেতে, আপনি কল / এক্সপ্রেশনটি মূল্যায়ন করেন, অর্থাত্, eval(.)এটিতে কল করুন। আমার বক্তব্যটি ছিল যে লোকেরা কলটি তৈরি করতে parse(text=.)বরং বরং quote(.)ইত্যাদি ব্যবহার করা উচিত যা পরে eval()এড হবে।
মার্টিন মাচলর

2
eval(quote())কয়েকটি ক্ষেত্রে কাজ করে তবে কিছু ক্ষেত্রে ব্যর্থ হবে যেখানে eval(parse())ভাল কাজ করবে।
নেলসনগন

18

বিকল্পভাবে, আপনি evalsআমার panderপ্যাকেজ থেকে কাঁচা ফলাফল সহ আউটপুট এবং সমস্ত সতর্কতা, ত্রুটি এবং অন্যান্য বার্তাগুলি ক্যাপচার করতে ব্যবহার করতে পারেন :

> pander::evals("5+5")
[[1]]
$src
[1] "5 + 5"

$result
[1] 10

$output
[1] "[1] 10"

$type
[1] "numeric"

$msg
$msg$messages
NULL

$msg$warnings
NULL

$msg$errors
NULL


$stdout
NULL

attr(,"class")
[1] "evals"

2
সুন্দর ফাংশন; evaluate::evaluateবাস্তবে ফলাফল অবজেক্ট ফিরিয়ে রেখে একটি গর্ত পূরণ করে; যা আপনার ফাংশনটিকে ম্যাক্লেপ্লি মাধ্যমে কল করার জন্য উপযুক্ত ব্যবহারের জন্য ছেড়ে দেয়। আমি আশা করি যে বৈশিষ্ট্যটি রয়ে গেছে!
রাসেলপিয়ার্স

আপনাকে ধন্যবাদ, রেপিয়ার্স এই ফাংশনটি মূলত আমাদের rapportপ্যাকেজের অংশ হিসাবে ২০১১ সালে রচিত হয়েছিল এবং তখন থেকে বেশ কয়েকটি অন্যান্য প্রকল্প ছাড়াও আমাদের র‌্যাপার্পোর্টার সার্ভিসে ভারী ব্যবহৃত হওয়ার কারণে সক্রিয়ভাবে রক্ষণাবেক্ষণ করা হয়েছে - সুতরাং আমি নিশ্চিত যে এটি একটি রক্ষণাবেক্ষণের জন্যই বজায় থাকবে যখন :) আমি আপনাকে এটি দরকারী বলে খুশী, আপনার সদয় প্রতিক্রিয়া জন্য ধন্যবাদ।
daroczig


2

একইভাবে ব্যবহার rlang:

eval(parse_expr("5+5"))

3
একটি rlangউত্তর খুঁজছেন এখানে এসেছেন তবে কি যদি এই ওভার বেস বিকল্পগুলির সুবিধা হয়? প্রকৃতপক্ষে, ব্যবহৃত কোডটির ঘনিষ্ঠ পরীক্ষায় দেখা যায় যে এটি আসলে ব্যবহার করা eval(parse(....))যা আমি এড়াতে চেয়েছিলাম।
নেলসনগন

4
কেবল negativeণাত্মকই নয়, এর নামটিও বিভ্রান্তিকর। এটি কোনও অভিব্যক্তির মূল্যায়ন করছে না। পার্স_টো_এক্সপ্রিটকে অন্য কিছু বলা উচিত যা ব্যবহারকারীকে বোঝে যে এটি চরিত্রের আর্গুমেন্টের উদ্দেশ্যে রয়েছে।
আইআরটিএফএম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.