কেন পলির পরিবর্তে মানচিত্র ব্যবহার করবেন?


170

আমার ব্যবহার করার কোনও কারণ আছে কি?

map(<list-like-object>, function(x) <do stuff>)

পরিবর্তে

lapply(<list-like-object>, function(x) <do stuff>)

আউটপুটটি একই হওয়া উচিত এবং আমি যে মানদণ্ডগুলি তৈরি করেছি তা দেখায় যে lapplyএটি কিছুটা দ্রুত (এটি mapসমস্ত অ-মানক-মূল্যায়ন ইনপুটকে মূল্যায়ন করার প্রয়োজন হিসাবে হওয়া উচিত )।

সুতরাং এরকম কোনও কারণের জন্য কেন আমাকে আসলে বদলে যাওয়া বিবেচনা করা উচিত purrr::map? আমি এখানে সিনট্যাক্স সম্পর্কে কারও পছন্দ বা অপছন্দ সম্পর্কে জিজ্ঞাসা করছি না, পুরর দ্বারা সরবরাহ করা অন্যান্য কার্যকারিতা ইত্যাদি, তবে স্ট্যান্ডার্ড মূল্যায়ন ব্যবহার করে অনুমানের purrr::mapসাথে তুলনা সম্পর্কে কঠোরভাবে । পারফরম্যান্স, ব্যতিক্রম হ্যান্ডলিং ইত্যাদির ক্ষেত্রে কোনও সুবিধা আছে কি ? নীচের মন্তব্যগুলি এটিকে বোঝায় না তবে সম্ভবত কেউ আরও কিছুটা বিশদভাবে বলতে পারেন?lapplymap(<list-like-object>, function(x) <do stuff>)purrr::map


8
সাধারণ ব্যবহারের ক্ষেত্রে প্রকৃতপক্ষে, বেস আর এর সাথে আরও ভালভাবে আঁকুন এবং নির্ভরতা এড়ান। আপনি যদি ইতিমধ্যে ততক্ষণ লোড করেন tidyverseতবে আপনি পাইপ %>%এবং ~ .x + 1
বেনাম

49
এটি বেশ প্রায় শৈলীর একটি প্রশ্ন। যদিও বেস বেস ফাংশনগুলি করে তা আপনার জানা উচিত, কারণ এই সমস্ত পরিপাটি উপাদানগুলি এটির উপরে কেবল একটি শেল। এক পর্যায়ে, সেই শেলটি ভেঙে যাবে।
হংক ওই

9
~{}শর্টকাট ল্যামডা (সহ বা ছাড়া {}প্লেইন জন্য আমার জন্য চুক্তি করুক purrr::map()। ধরণ-প্রয়োগকারী purrr::map_…()কুশলী এবং কম ভোঁতা তুলনায় vapply()purrr::map_df()একটি সুপার ব্যয়বহুল ফাংশন কিন্তু এটি সহজসাধ্য কোড। সেখানে বেস আর সঙ্গে স্টিকিং সঙ্গে কিছুই ভুল একেবারে এর [lsv]apply(), যদিও ।
hrbrmstr

4
প্রশ্নের জন্য আপনাকে ধন্যবাদ - ধরণের জিনিস আমিও তাকিয়েছিলাম। আমি 10 বছরেরও বেশি সময় ধরে আর ব্যবহার করছি এবং নিশ্চিতভাবে purrrস্টাফ ব্যবহার করব না এবং ব্যবহার করব না । আমার বক্তব্যটি নিম্নরূপ: tidyverseবিশ্লেষণ / ইন্টারেক্টিভ / রিপোর্টিং স্টাফের জন্য কল্পিত, প্রোগ্রামিংয়ের জন্য নয়। আপনি যদি ব্যবহার করতে থাকেন lapplyবা mapতারপরে আপনি প্রোগ্রামিং করছেন এবং প্যাকেজ তৈরির সাথে একদিন শেষ হতে পারে। তারপরে কম নির্ভরতা সবচেয়ে ভাল। প্লাস: আমি কখনও কখনও লোকদের mapপরে বেশ অস্পষ্ট সিনট্যাক্স ব্যবহার করে দেখি । এবং এখন আমি পারফরম্যান্স টেস্ট দেখছি: আপনি যদি applyপরিবারে অভ্যস্ত হন: এটি আটকে থাকুন।
এরিক লেকাউত্রে

4
টিম আপনি লিখেছেন: "আমি এখানে সিনট্যাক্স সম্পর্কে কারও পছন্দ বা অপছন্দ সম্পর্কে জিজ্ঞাসা করছি না, পুরর দ্বারা প্রদত্ত অন্যান্য কার্যকারিতা ইত্যাদি, তবে স্ট্যান্ডার্ড মূল্যায়ন ব্যবহার করে দোষী সাব্যস্ত করে মানচিত্রের তুলনা সম্পর্কে কঠোরভাবে জিজ্ঞাসা করছি না" এবং আপনি যে উত্তরটি স্বীকার করেছেন তা হ'ল আপনি যা বলেছিলেন ঠিক সেইভাবেই যা চলেছে আপনি চান না যে লোকেদের উপর দিয়ে যায়।
কার্লোস সিনেলি

উত্তর:


231

আপনি যদি purrr থেকে কেবলমাত্র ফাংশনটি ব্যবহার করেন map()তবে তা না, সুবিধাগুলি যথেষ্ট নয়। সমৃদ্ধ পাউলো যেমন উল্লেখ করেছেন, সেই হেল্পারদের প্রধান সুবিধা map()হ'ল যা আপনাকে সাধারণ বিশেষ ক্ষেত্রে কমপ্যাক্ট কোড লেখার অনুমতি দেয়:

  • ~ . + 1 সমতুল্য function(x) x + 1

  • list("x", 1)সমতূল্য function(x) x[["x"]][[1]]। এই সাহায্যকারীরা কিছুটা বেশি সাধারণ [[- ?pluckবিশদ বিবরণ দেখুন। জন্য ডেটা rectangling , .defaultযুক্তি বিশেষ করে সহায়ক।

তবে বেশিরভাগ সময় আপনি কোনও একক *apply()/ map() ফাংশন ব্যবহার করছেন না , আপনি সেগুলির একটি গুচ্ছ ব্যবহার করছেন, এবং পিউরারের সুবিধা ফাংশনগুলির মধ্যে অনেক বেশি ধারাবাহিকতা। উদাহরণ স্বরূপ:

  • প্রথম যুক্তিটি lapply()হ'ল ডেটা; প্রথম যুক্তি mapply()হ'ল ফাংশন। সমস্ত মানচিত্র ফাংশন প্রথম যুক্তি সর্বদা ডেটা হয়।

  • সহ vapply(), sapply()এবং mapply()আপনি এর সাথে আউটপুটে নাম দমন করতে বেছে নিতে পারেন USE.NAMES = FALSE; তবে lapply()সেই যুক্তি নেই।

  • ম্যাপার ফাংশনটিতে ধারাবাহিক যুক্তিগুলি পাস করার কোনও সুসংগত উপায় নেই's সর্বাধিক ফাংশন ব্যবহার ...কিন্তু mapply()ব্যবহারসমূহ MoreArgs(যা আপনি আশা করতে চাই বলা হবে MORE.ARGS), এবং Map(), Filter()এবং Reduce()যদি আপনি একটি নতুন বেনামী ফাংশন তৈরি করতে আশা। মানচিত্রের কার্যগুলিতে স্থির যুক্তি সর্বদা ফাংশনটির নামের পরে আসে।

  • প্রায় প্রতিটি purrr ফাংশন টাইপ স্থিতিশীল: আপনি ফাংশন নাম থেকে একচেটিয়াভাবে আউটপুট টাইপ পূর্বাভাস করতে পারেন। এটি sapply()বা এর জন্য সত্য নয় mapply()। হ্যাঁ, আছে vapply(); তবে এর সমতুল্য নেই mapply()

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

Purrr কিছু সুবিধাজনক মানচিত্রের ভেরিয়েন্টগুলি পূরণ করে যা বেস আর থেকে অনুপস্থিত:

  • modify()[[<-"জায়গায়" সংশোধন করতে ব্যবহার করে ডেটা ধরণের সংরক্ষণ করে । _ifভেরিয়েন্টের সাথে একত্রে এটি (আইএমও সুন্দর) কোডটির জন্য অনুমতি দেয়modify_if(df, is.factor, as.character)

  • map2()আপনাকে একই সাথে মানচিত্রের অনুমতি দেয় xএবং y। এটি মতামত প্রকাশ করা সহজ করে তোলে makes map2(models, datasets, predict)

  • imap()আপনাকে একই সাথে মানচিত্র তৈরি করতে দেয় xএবং এর সূচকগুলি (নাম বা অবস্থান হয়)। এটি (উদাহরণস্বরূপ) csvডিরেক্টরিতে সমস্ত ফাইল লোড করা সহজ করে দেয় filenameএবং প্রতিটিটিতে একটি কলাম যুক্ত হয়।

    dir("\\.csv$") %>%
      set_names() %>%
      map(read.csv) %>%
      imap(~ transform(.x, filename = .y))
  • walk()অদৃশ্যভাবে তার ইনপুট ফেরত দেয়; এবং যখন আপনি কোনও পার্শ্ব প্রতিক্রিয়া (যেমন ডিস্কে ফাইলগুলি লেখার জন্য) কোনও ফাংশন কল করছেন তখন দরকারী)

অন্যান্য সহায়ক safely()এবং পছন্দ মত উল্লেখ না partial()

ব্যক্তিগতভাবে, আমি দেখতে পাচ্ছি যে আমি যখন পূরার ব্যবহার করি তখন আমি কম ঘর্ষণ এবং বৃহত্তর স্বাচ্ছন্দ্যে ফাংশনাল কোডটি লিখতে পারি; এটি একটি ধারণা চিন্তা এবং এটি বাস্তবায়নের মধ্যে ব্যবধান হ্রাস করে। কিন্তু আপনার মাইলেজ পরিবর্তিত হতে পারে; Purrr ব্যবহার করার দরকার নেই যতক্ষণ না এটি আসলে আপনাকে সহায়তা করে।

Microbenchmarks

হ্যাঁ, map()তুলনায় কিছুটা ধীর lapply()। তবে ব্যবহারের ব্যয় map()বা lapply()আপনি যা ম্যাপিং করছেন তার দ্বারা চালিত হয়, লুপটি সম্পাদন করার ওভারহেড নয়। নীচের মাইক্রোব্যাঙ্কমার্ক পরামর্শ দেয় যে map()তুলনায় ব্যয়টির lapply()পরিমাণ প্রতি উপাদান প্রায় 40 এনএস, যা বেশিরভাগ আর কোডকে বৈধভাবে প্রভাবিত করার সম্ভাবনা কম বলে মনে হয়।

library(purrr)
n <- 1e4
x <- 1:n
f <- function(x) NULL

mb <- microbenchmark::microbenchmark(
  lapply = lapply(x, f),
  map = map(x, f)
)
summary(mb, unit = "ns")$median / n
#> [1] 490.343 546.880

2
আপনি কি উদাহরণটিতে ট্রান্সফর্ম () ব্যবহার করতে চান? বেস আর ট্রান্সফর্ম () এর মতো, বা আমি কি কিছু মিস করছি? রূপান্তর () আপনাকে একটি ফ্যাক্টর হিসাবে ফাইলের নাম দেয়, যা সতর্কতা উত্পন্ন করে যখন আপনি (স্বাভাবিকভাবে) এক সাথে সারি আবদ্ধ করতে চান। মিউটেট () আমাকে যে ফাইল ফাইলগুলির চান তার অক্ষর কলাম দেয়। সেখানে এটি ব্যবহার না করার কোনও কারণ আছে?
ডক্টরজি

2
হ্যাঁ, ব্যবহার করা আরও ভাল mutate(), আমি কেবল অন্য কোনও ডিপগুলি সহ একটি সাধারণ উদাহরণ চাইছিলাম।
হ্যাডলি

এই উত্তরটিতে কোথাও টাইপ-স্পেসিফিকেশন প্রদর্শন করা উচিত নয়? map_*এটাই আমাকে purrrঅনেক স্ক্রিপ্টে লোড করে দিয়েছে । এটি আমার কোড ( stopifnot(is.data.frame(x))) এর কিছু 'নিয়ন্ত্রণ প্রবাহ' দিকগুলিতে আমাকে সহায়তা করেছিল ।
Fr.

2
ggplot এবং ডেটা টেবিল দুর্দান্ত, তবে আমাদের কি আর-এর প্রতিটি ফাংশনের জন্য একটি নতুন প্যাকেজ দরকার?
adn বিপিএস

57

তুলনা purrrএবং lapplyনিচে boils সুবিধা এবং গতি


1. purrr::mapল্যাংলি চেয়ে সিনথেটিকভাবে আরও সুবিধাজনক

তালিকার দ্বিতীয় উপাদানটি বের করুন

map(list, 2)  

যা @F হিসাবে। প্রিভি উল্লেখ করেছেন, একই:

map(list, function(x) x[[2]])

সঙ্গে lapply

lapply(list, 2) # doesn't work

আমাদের একটি বেনামী ফাংশন পাস করতে হবে ...

lapply(list, function(x) x[[2]])  # now it works

... বা @ রিচসক্রিভেন উল্লেখ করেছেন, আমরা [[একটি যুক্তি হিসাবে পাস করিlapply

lapply(list, `[[`, 2)  # a bit more simple syntantically

সুতরাং যদি নিজেকে ব্যবহার করে অনেক তালিকায় ফাংশন প্রয়োগ করা lapplyএবং কোনও কাস্টম ফাংশন সংজ্ঞায়িত করার বা কোনও বেনামে ফাংশন লেখার ক্লান্তি খুঁজে পাওয়া যায় তবে সুবিধার্থে পক্ষে যাওয়ার পক্ষে এক কারণ purrr

২. টাইপ-নির্দিষ্ট মানচিত্রে কোডের অনেকগুলি লাইন কাজ করে

  • map_chr()
  • map_lgl()
  • map_int()
  • map_dbl()
  • map_df()

এই প্রতিটি নির্দিষ্ট ধরণের মানচিত্রের ফাংশনগুলি পরমাণু তালিকা (ভেক্টর) ফিরিয়ে দেয় map()এবং পরিবর্তিত তালিকার পরিবর্তে lapply()। যদি আপনি এর মধ্যে পারমাণবিক ভেক্টরের নেস্টেড তালিকাগুলি নিয়ে কাজ করে থাকেন তবে আপনি সরাসরি এই ভেক্টরগুলিকে টেনে আনতে এই ধরণের নির্দিষ্ট মানচিত্রের ফাংশনগুলি ব্যবহার করতে পারেন, এবং সরাসরি ভেক্টরগুলিকে সরাসরি ইনট, ডিবিএল, সিআর ভেক্টরগুলিতে জোর করতে পারেন। বেস আর সংস্করণ ভালো কিছু দেখাবে as.numeric(sapply(...)), as.character(sapply(...))ইত্যাদি

map_<type>ফাংশন এছাড়াও দরকারী মানের যে যদি তারা নির্দেশিত ধরনের একটি পারমাণবিক ভেক্টর আসতে পারে না, তারা ব্যর্থ হয়েছে। কিছু নিয়ন্ত্রণ প্রবাহ সংজ্ঞায়িত করার সময় এটি দরকারী, যেখানে আপনি কোনও ফাংশন ব্যর্থ করতে চান যদি এটি [কোনওভাবে] ভুল অবজেক্টের ধরণের উত্পন্ন করে।

৩. সুবিধা সুবিধার lapplyদিক থেকে [সামান্য] দ্রুতmap

purrr@F হিসাবে সুবিধামত ফাংশন ব্যবহার করা হচ্ছে । প্রাইভের নির্দেশিত প্রক্রিয়াটি কিছুটা কমিয়ে দেয়। আসুন আমি উপরে উপস্থাপন 4 কেস প্রতিযোগিতা।

# devtools::install_github("jennybc/repurrrsive")
library(repurrrsive)
library(purrr)
library(microbenchmark)
library(ggplot2)

mbm <- microbenchmark(
lapply       = lapply(got_chars[1:4], function(x) x[[2]]),
lapply_2     = lapply(got_chars[1:4], `[[`, 2),
map_shortcut = map(got_chars[1:4], 2),
map          = map(got_chars[1:4], function(x) x[[2]]),
times        = 100
)
autoplot(mbm)

এখানে চিত্র বর্ণনা লিখুন

এবং বিজয়ী....

lapply(list, `[[`, 2)

মোট কথা, কাঁচা গতি যদি আপনার পরে হয়: base::lapply(যদিও এটি এত দ্রুত নয়)

সাধারণ বাক্য গঠন এবং প্রকাশের জন্য: purrr::map


এই চমৎকার purrrটিউটোরিয়াল হাইলাইট সুবিধা ব্যবহার করে যখন স্পষ্টভাবে বেনামী ফাংশন লিখতে হচ্ছে না purrr, এবং টাইপ-নির্দিষ্ট সুবিধাগুলো mapফাংশন।


2
মনে রাখবেন যে আপনি যদি ন্যায়বিচারের function(x) x[[2]]পরিবর্তে ব্যবহার করেন 2তবে এটি কম ধীর হবে। এই সমস্ত অতিরিক্ত সময় চেকগুলি করার কারণে হয় lapply
এফ Privé

17
আপনার বেনামি ফাংশনগুলির "দরকার" নেই। [[একটি ফাংশন। আপনি করতে পারেন lapply(list, "[[", 3)
সমৃদ্ধ স্ক্রিভেন

পছন্দ করুন এটি ল্যাপলি ওভার প্যুরারের জন্য সিনট্যাক্সকে সহজ করে তোলে।
ধনী পলু

37

যদি আমরা স্বাদের দিকগুলি বিবেচনা না করি (অন্যথায় এই প্রশ্নটি বন্ধ করা উচিত) বা সিনট্যাক্সের ধারাবাহিকতা, শৈলী ইত্যাদি, উত্তরটি হ'ল না, প্রয়োগের পরিবারের mapপরিবর্তে lapplyবা স্ট্রাইক্টারের মতো অন্যান্য রূপগুলি ব্যবহার করার কোনও বিশেষ কারণ নেই vapply

পিএস: এই লোকগুলিকে কৃত্রিমভাবে কমিয়ে দেওয়ার জন্য, কেবল ওপি লিখেছেন মনে রাখবেন:

আমি এখানে সিনট্যাক্স সম্পর্কে কারও পছন্দ বা অপছন্দ সম্পর্কে জিজ্ঞাসা করছি না, পুরর দ্বারা প্রদত্ত অন্যান্য কার্যকারিতা ইত্যাদি, তবে কঠোরভাবে তুলির তুলনা সম্পর্কে :: মানচিত্রটি স্তম্ভিতভাবে মানক মূল্যায়ন ব্যবহার করে ধরে নেওয়া

আপনি যদি বাক্য গঠন এবং এর অন্যান্য কার্যকারিতা বিবেচনা না purrrকরেন তবে ব্যবহারের কোনও বিশেষ কারণ নেই map। আমি purrrনিজেকে ব্যবহার করি এবং হ্যাডলির উত্তরের সাথে আমি ভাল আছি, তবে ওপি যে বিষয়গুলি তিনি জিজ্ঞাসা করছেন না বলে জানিয়েছে তা খুব হাস্যকর বিষয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.