FUN এর ভিতরে ল্যাপলি সূচকের নামগুলি অ্যাক্সেস করুন


162

আমার ল্যাপলি () ফাংশনে তালিকা সূচক নাম পাওয়ার কোনও উপায় আছে কি?

n = names(mylist)
lapply(mylist, function(list.elem) { cat("What is the name of this list element?\n" })

আমি জিজ্ঞাসা করলাম সামনে যদি এটা lapply () সূচক নাম সংরক্ষণে সম্ভব ফিরে তালিকা, কিন্তু আমি এখনও যদি কাস্টম ফাংশন ভিতরে প্রতিটি উপাদান নাম আনা একটি সহজ উপায় জানি না। আমি নিজের নামগুলিতে ল্যাপলি কল করা এড়াতে চাই, আমি বরং ফাংশন প্যারামিটারগুলিতে নামটি পেয়েছি।


গুণাবলী সহ আরও একটি কৌশল আছে। এখানে দেখুন: stackoverflow.com/questions/4164960/... কি DWin হয়েছে অনুরূপ, কিন্তু বিভিন্ন ধরনের যা। :)
রোমান Luštrik

উত্তর:


161

দুর্ভাগ্যক্রমে, lapplyকেবলমাত্র ভেক্টরের যে উপাদানগুলি আপনি এটি দিয়েছিলেন সেগুলি আপনাকে দেয়। স্বাভাবিক কাজটি হ'ল এটি ভেক্টরের পরিবর্তে ভেক্টরের নাম বা সূচকগুলি পাস করা।

তবে মনে রাখবেন যে আপনি সর্বদা ফাংশনে অতিরিক্ত যুক্তি উপস্থাপন করতে পারেন, সুতরাং নিম্নলিখিতটি কাজ করে:

x <- list(a=11,b=12,c=13) # Changed to list to address concerns in commments
lapply(seq_along(x), function(y, n, i) { paste(n[[i]], y[[i]]) }, y=x, n=names(x))

এখানে আমি lapplyসূচকগুলি ব্যবহার করি xতবে পাস xএবং এর নামগুলিও ব্যবহার করি x। যেমন আপনি দেখতে পাচ্ছেন, ফাংশন আর্গুমেন্টগুলির ক্রম কিছু হতে পারে - অতিরিক্ত lapplyউপাদানগুলির মধ্যে নির্দিষ্ট না করে প্রথম যুক্তিতে "উপাদান" (এখানে সূচক) পাস করবে । এই ক্ষেত্রে, আমি উল্লেখ করেছি yএবং nতাই কেবল আছেi বাকি আছে ...

যা নিম্নলিখিত উত্পাদন করে:

[[1]]
[1] "a 11"

[[2]]
[1] "b 12"

[[3]]
[1] "c 13"

আপডেট সহজ উদাহরণ, একই ফলাফল:

lapply(seq_along(x), function(i) paste(names(x)[[i]], x[[i]]))

এখানে ফাংশনটি "গ্লোবাল" ভেরিয়েবল ব্যবহার xকরে এবং প্রতিটি কলে নামগুলি বের করে।


কাস্টম ফাংশনে কীভাবে 'i' প্যারামিটারটি আরম্ভ করা হয়?
রবার্ট কুবারিক

এটি পেয়েছেন, সুতরাং ল্যাপলি () সত্যিকার অর্থে seq_along দ্বারা ফিরে আসা উপাদানগুলির জন্য প্রযোজ্য। আমি বিভ্রান্ত হয়ে পড়েছি কারণ কাস্টম ফাংশন প্যারামিটারগুলি পুনরায় সাজানো হয়েছিল। সাধারণত পুনরাবৃত্ত তালিকার উপাদানটি হ'ল প্রথম প্যারামিটার।
রবার্ট কুব্রিক

আপডেট উত্তর এবং পরিবর্তে প্রথম ফাংশনটি ব্যবহার yকরে পরিবর্তিত হয়েছে xযাতে এটি (আশাবাদী) আরও স্পষ্ট হয় যে ফাংশনটি তার আর্গুমেন্টগুলিকে যে কোনও কিছু বলতে পারে। ভেক্টরের মানগুলিতেও পরিবর্তন করা হয়েছে 11,12,13
টমি

@ রবার্টকুব্রিক - হ্যাঁ, আমি সম্ভবত একবারে অনেকগুলি দেখানোর চেষ্টা করেছি ... আপনি যুক্তিগুলির কোনও নাম রাখতে পারেন এবং সেগুলি কোনও ক্রমে রাখতে পারেন।
টমি 21

@ ডিউইন - আমি মনে করি এটি সঠিক (এবং তালিকাগুলিতেও প্রয়োগ হয়) ;-) ... তবে দয়া করে আমাকে ভুল প্রমাণ করুন!
টমি

48

এটি মূলত টমির মতো একই ব্যবহার করে, তবে এর সাথে Map()তালিকার উপাদানগুলির নাম সংরক্ষণ করে এমন বৈশ্বিক ভেরিয়েবলগুলি অ্যাক্সেস করার দরকার নেই।

> x <- list(a=11, b=12, c=13)
> Map(function(x, i) paste(i, x), x, names(x))
$a
[1] "a 11"

$b
[1] "b 12"

$c
[1] "c 13

বা, আপনি যদি পছন্দ করেন mapply()

> mapply(function(x, i) paste(i, x), x, names(x))
     a      b      c 
"a 11" "b 12" "c 13"

এটি অবশ্যই গুচ্ছের সেরা সমাধান।
EmilBeBri

ব্যবহার করার সময় mapply(), SIMPLIFYবিকল্পটি লক্ষ্য করুন , যা সত্যের ডিফল্ট হয়। আমার ক্ষেত্রে, এটি কেবলমাত্র একটি সাধারণ তালিকা প্রয়োগ করতে চাইলে এটি পুরোপুরি একটি বড় ম্যাট্রিক্সে পরিণত করে। এটিকে F(এর অভ্যন্তরে mapply()) সেট করা এটিকে উদ্দেশ্য হিসাবে চালিত করে।
স্বচ্ছতার জন্য জেজে এবং মনিকা

39

আর সংস্করণ 3.2 এর জন্য আপডেট করুন

দাবি অস্বীকার: এটি একটি হ্যাকিং কৌশল এবং পরবর্তী প্রকাশগুলিতে কাজ বন্ধ করে দিতে পারে।

আপনি এটি ব্যবহার করে সূচকটি পেতে পারেন:

> lapply(list(a=10,b=20), function(x){parent.frame()$i[]})
$a
[1] 1

$b
[1] 2

দ্রষ্টব্য: [] কাজ করার জন্য এটি প্রয়োজনীয়, কারণ এটি এই চিন্তায় রত করে যে প্রতীকটির i(মূল্যায়নের ফ্রেমে থাকা lapply) আরও রেফারেন্স থাকতে পারে, সুতরাং এটি অলস প্রতিলিপি সক্রিয় করে। এটি ছাড়া আর আর আলাদা আলাদা কপি রাখবে না i:

> lapply(list(a=10,b=20), function(x){parent.frame()$i})
$a
[1] 2

$b
[1] 2

অন্যান্য বহিরাগত উপায়গুলির মত ব্যবহৃত হতে পারে function(x){parent.frame()$i+0}বা function(x){--parent.frame()$i}

পারফরম্যান্স ইমপ্যাক্ট

বাধ্য নকলটি কর্মক্ষমতা হ্রাসের কারণ হবে? হ্যাঁ! মানদণ্ডগুলি এখানে:

> x <- as.list(seq_len(1e6))

> system.time( y <- lapply(x, function(x){parent.frame()$i[]}) )
user system elapsed
2.38 0.00 2.37
> system.time( y <- lapply(x, function(x){parent.frame()$i[]}) )
user system elapsed
2.45 0.00 2.45
> system.time( y <- lapply(x, function(x){parent.frame()$i[]}) )
user system elapsed
2.41 0.00 2.41
> y[[2]]
[1] 2

> system.time( y <- lapply(x, function(x){parent.frame()$i}) )
user system elapsed
1.92 0.00 1.93
> system.time( y <- lapply(x, function(x){parent.frame()$i}) )
user system elapsed
2.07 0.00 2.09
> system.time( y <- lapply(x, function(x){parent.frame()$i}) )
user system elapsed
1.89 0.00 1.89
> y[[2]]
[1] 1000000

উপসংহার

এই উত্তরটি কেবল এটি দেখায় যে আপনার এটি ব্যবহার করা উচিত নয় ... আপনি যদি টমির উপরের মতো আরও একটি সমাধান খুঁজে পান এবং ভবিষ্যতের মুক্তির সাথে আরও সামঞ্জস্যপূর্ণ হন তবে আপনার কোডটি আরও পাঠযোগ্য হবে না, তবে মূল দলটি যে কঠোর পরিশ্রম করেছে সেগুলিও আপনি হারাতে পারবেন risk বিকাশ!


পুরানো সংস্করণের কৌশলগুলি আর কাজ করছে না:

> lapply(list(a=10,b=10,c=10), function(x)substitute(x)[[3]])

ফলাফল:

$a
[1] 1

$b
[1] 2

$c
[1] 3

ব্যাখ্যা: lapplyফর্মের কল সৃষ্টি FUN(X[[1L]], ...), FUN(X[[2L]], ...)ইত্যাদি সুতরাং যুক্তি এটি পাস হয় X[[i]]যেখানে iলুপ বর্তমান সূচি। আমরা যদি এটির মূল্যায়নের আগে এটি পাই (যেমন, আমরা যদি ব্যবহার করি substitute), আমরা অমূল্য অভিব্যক্তি পাই X[[i]]। এটি [[আর্গুমেন্ট সহ ফাংশন করার জন্য একটি কলX (প্রতীক) এবং i(একটি পূর্ণসংখ্যার) । সুতরাংsubstitute(x)[[3]] এই পূর্ণসংখ্যার অবিকল ফিরে আসে।

সূচকটি থাকার পরে আপনি নামগুলি তুচ্ছভাবে অ্যাক্সেস করতে পারেন, যদি আপনি এটির আগে এটি সংরক্ষণ করেন:

L <- list(a=10,b=10,c=10)
n <- names(L)
lapply(L, function(x)n[substitute(x)[[3]]])

ফলাফল:

$a
[1] "a"

$b
[1] "b"

$c
[1] "c"

বা এই দ্বিতীয় কৌশলটি ব্যবহার করে: :-)

lapply(list(a=10,b=10,c=10), function(x)names(eval(sys.call(1)[[2]]))[substitute(x)[[3]]])

(ফলাফল একই)

ব্যাখ্যা ২: sys.call(1)প্রত্যাবর্তন lapply(...), সুতরাং এটি sys.call(1)[[2]]তালিকা আর্গুমেন্ট হিসাবে ব্যবহৃত এক্সপ্রেশন lapply। এটি পাস করা evalএকটি বৈধ অবজেক্ট তৈরি করেnames অ্যাক্সেস করতে পারে। কৌতুকময়, তবে এটি কার্যকর।

বোনাস: নাম পাওয়ার দ্বিতীয় উপায়:

lapply(list(a=10,b=10,c=10), function(x)eval.parent(quote(names(X)))[substitute(x)[[3]]])

নোটটি এটির Xপ্যারেন্ট ফ্রেমে একটি বৈধ অবজেক্ট FUNএবং এর তালিকা আর্গুমেন্টের উল্লেখ রয়েছে lapply, তাই আমরা এটির সাথে এটি পেতে পারি eval.parent


2
কোডটি lapply(list(a=10,b=10,c=10), function(x)substitute(x)[[3]])সমস্ত 3. হিসাবে ফিরে আসছে আপনি কী ব্যাখ্যা করতে পারবেন যে এই 3 টি কীভাবে বেছে নেওয়া হয়েছিল? এবং তাত্পর্য জন্য কারণ? এই ক্ষেত্রে তালিকার দৈর্ঘ্যের সমান, ৩. দুঃখিত, এটি যদি একটি প্রাথমিক প্রশ্ন তবে সাধারণ ক্ষেত্রে এটি কীভাবে প্রয়োগ করতে হয় তা জানতে চাই।
আনুশা

@ আনুশা, প্রকৃতপক্ষে, এই ফর্মটি আর কাজ করছে না ... তবে lapply(list(a=10,b=10,c=10), function(x)eval.parent(quote(names(X)))[substitute(x)[[3]]])কাজগুলি ... আমি যা যা চলছে তা পরীক্ষা করব।
ফার্ডিনান্ড.ক্রাফ্ট

@ ফারডিনানড.ক্রাফ্ট, lapply(list(a=10,b=10,c=10), function(x)eval.parent(quote(names(X)))[substitute(x)[[3]]])আর কাজ করছে না এবং একটি ত্রুটি দেয়, Error in eval.parent(quote(names(X)))[substitute(x)[[3]]] : invalid subscript type 'symbol'এটি ঠিক করার কোনও সহজ উপায় আছে কি?
পূর্বাভাসকারী

আপনাকে অনেক ধন্যবাদ @ ফার্ডিনানড.ক্যাফট
ফোরকাস্টার

18

আমি অনেকবার একই সমস্যা পেয়েছি ... আমি অন্য উপায়ে ব্যবহার শুরু করেছি ... ব্যবহারের পরিবর্তে lapply, আমি ব্যবহার শুরু করেছিmapply

n = names(mylist)
mapply(function(list.elem, names) { }, list.elem = mylist, names = n)

2
আমি এটিও পছন্দ করি তবে এই উত্তরটি পূর্বের উত্তরটির সদৃশ ।
মার্ভ

13

আপনি প্যাকেজ imap()থেকে ব্যবহার করার চেষ্টা করতে পারেন purrr

ডকুমেন্টেশন থেকে:

ইম্যাপ (এক্স, ...) হ'ল ম্যাপ 2 (এক্স, নাম (এক্স), ...) এর সংক্ষিপ্ত হাত, যদি x এর নাম, বা ম্যাপ 2 থাকে (x, seq_along (x), ...) যদি তা না থাকে।

সুতরাং, আপনি এটি সেভাবে ব্যবহার করতে পারেন:

library(purrr)
myList <- list(a=11,b=12,c=13) 
imap(myList, function(x, y) paste(x, y))

যা আপনাকে নিম্নলিখিত ফলাফল দেবে:

$a
[1] "11 a"

$b
[1] "12 b"

$c
[1] "13 c"

10

শুধু নাম লুপ।

sapply(names(mylist), function(n) { 
    doSomething(mylist[[n]])
    cat(n, '\n')
}

এটি অবশ্যই সহজ সমাধান।
উড়ে

1
@ ফ্লাইস: হ্যাঁ, mylistফাংশনের অভ্যন্তরে হার্ড-কোড ভেরিয়েবলের খারাপ অভ্যাস বাদে । আরও ভাল করণীয়function(mylist, nm) ...
স্মি

5

টমির উত্তরটি নামযুক্ত ভেক্টরগুলিতে প্রযোজ্য তবে আপনি তালিকায় আগ্রহী এমন ধারণাটি পেয়েছি। এবং দেখে মনে হচ্ছে তিনি শেষের দিকে করছিলেন কারণ তিনি কলিং পরিবেশ থেকে "এক্স" উল্লেখ করছেন। এই ফাংশনটি কেবলমাত্র প্যারামিটারগুলি ব্যবহার করে যা ফাংশনে উত্তীর্ণ হয়েছিল এবং সুতরাং পাস হওয়া বস্তুর নাম সম্পর্কে কোনও অনুমান করে না:

x <- list(a=11,b=12,c=13)
lapply(x, function(z) { attributes(deparse(substitute(z)))$names  } )
#--------
$a
NULL

$b
NULL

$c
NULL
#--------
 names( lapply(x, function(z) { attributes(deparse(substitute(z)))$names  } ))
#[1] "a" "b" "c"
 what_is_my_name <- function(ZZZ) return(deparse(substitute(ZZZ)))
 what_is_my_name(X)
#[1] "X"
what_is_my_name(ZZZ=this)
#[1] "this"
 exists("this")
#[1] FALSE

আপনার ফাংশন কি কেবল ফেরত NULL?! সুতরাং lapply(x, function(x) NULL)একই উত্তর দেয় ...
টমি

মনে রাখবেন যে lapplyসর্বদা xফলাফলের পরে নামগুলি যুক্ত করে ।
টমি 21

হ্যাঁ. সম্মত হন যে এই অনুশীলনের পাঠ।
আইআরটিএফএম

4

আমার উত্তর টমির এবং কারাকালগুলির মতো একই দিকে চলে যায় তবে অতিরিক্ত বিষয় হিসাবে তালিকাটি সংরক্ষণ করতে এড়ানো যায় না।

lapply(seq(3), function(i, y=list(a=14,b=15,c=16)) { paste(names(y)[[i]], y[[i]]) })

ফলাফল:

[[1]]
[1] "a 14"

[[2]]
[1] "b 15"

[[3]]
[1] "c 16"

এটি তালিকাটিকে FU- এর নাম দেওয়া যুক্তি হিসাবে দেয় (পরিবর্তে ল্যাপ্লি)। ল্যাপলি কেবল তালিকার উপাদানগুলির উপর পুনরাবৃত্তি করতে হবে (তালিকার দৈর্ঘ্য পরিবর্তন করার সময় এই প্রথম যুক্তিটি ল্যাপ্লিতে পরিবর্তন করতে সাবধান হন)।

দ্রষ্টব্য: অতিরিক্ত যুক্তি হিসাবে ল্যাপ্লিতে সরাসরি তালিকা দেওয়া কাজ করে:

lapply(seq(3), function(i, y) { paste(names(y)[[i]], y[[i]]) }, y=list(a=14,b=15,c=16))

3

উভয় @caracals এবং @Tommy ভালো সমাধান এবং এটি সহ একটি উদাহরণ listএবং data.frameআছে।
rএকটি হল listএর listএবং data.frameএর ( dput(r[[1]]শেষে)।

names(r)
[1] "todos"  "random"
r[[1]][1]
$F0
$F0$rst1
   algo  rst  prec  rorac prPo pos
1  Mean 56.4 0.450 25.872 91.2 239
6  gbm1 41.8 0.438 22.595 77.4 239
4  GAM2 37.2 0.512 43.256 50.0 172
7  gbm2 36.8 0.422 18.039 85.4 239
11 ran2 35.0 0.442 23.810 61.5 239
2  nai1 29.8 0.544 52.281 33.1 172
5  GAM3 28.8 0.403 12.743 94.6 239
3  GAM1 21.8 0.405 13.374 68.2 239
10 ran1 19.4 0.406 13.566 59.8 239
9  svm2 14.0 0.385  7.692 76.2 239
8  svm1  0.8 0.359  0.471 71.1 239

$F0$rst5
   algo  rst  prec  rorac prPo pos
1  Mean 52.4 0.441 23.604 92.9 239
7  gbm2 46.4 0.440 23.200 83.7 239
6  gbm1 31.2 0.416 16.421 79.5 239
5  GAM3 28.8 0.403 12.743 94.6 239
4  GAM2 28.2 0.481 34.815 47.1 172
11 ran2 26.6 0.422 18.095 61.5 239
2  nai1 23.6 0.519 45.385 30.2 172
3  GAM1 20.6 0.398 11.381 75.7 239
9  svm2 14.4 0.386  8.182 73.6 239
10 ran1 14.0 0.390  9.091 64.4 239
8  svm1  6.2 0.370  3.584 72.4 239

উদ্দেশ্যটি unlistসমস্ত তালিকাতে রয়েছে, listকেস সনাক্ত করতে কলাম হিসাবে ass নামের ক্রম রেখে ।

r=unlist(unlist(r,F),F)
names(r)
[1] "todos.F0.rst1"  "todos.F0.rst5"  "todos.T0.rst1"  "todos.T0.rst5"  "random.F0.rst1" "random.F0.rst5"
[7] "random.T0.rst1" "random.T0.rst5"

তালিকাগুলি তালিকাভুক্ত করুন তবে। গুলি নয় data.frame

ra=Reduce(rbind,Map(function(x,y) cbind(case=x,y),names(r),r))

Mapকলাম হিসাবে নামের ক্রম রাখে। Reduceসমস্ত যোগদান data.frame

head(ra)
            case algo  rst  prec  rorac prPo pos
1  todos.F0.rst1 Mean 56.4 0.450 25.872 91.2 239
6  todos.F0.rst1 gbm1 41.8 0.438 22.595 77.4 239
4  todos.F0.rst1 GAM2 37.2 0.512 43.256 50.0 172
7  todos.F0.rst1 gbm2 36.8 0.422 18.039 85.4 239
11 todos.F0.rst1 ran2 35.0 0.442 23.810 61.5 239
2  todos.F0.rst1 nai1 29.8 0.544 52.281 33.1 172

পিএস r[[1]]:

    structure(list(F0 = structure(list(rst1 = structure(list(algo = c("Mean", 
    "gbm1", "GAM2", "gbm2", "ran2", "nai1", "GAM3", "GAM1", "ran1", 
    "svm2", "svm1"), rst = c(56.4, 41.8, 37.2, 36.8, 35, 29.8, 28.8, 
    21.8, 19.4, 14, 0.8), prec = c(0.45, 0.438, 0.512, 0.422, 0.442, 
    0.544, 0.403, 0.405, 0.406, 0.385, 0.359), rorac = c(25.872, 
    22.595, 43.256, 18.039, 23.81, 52.281, 12.743, 13.374, 13.566, 
    7.692, 0.471), prPo = c(91.2, 77.4, 50, 85.4, 61.5, 33.1, 94.6, 
    68.2, 59.8, 76.2, 71.1), pos = c(239L, 239L, 172L, 239L, 239L, 
    172L, 239L, 239L, 239L, 239L, 239L)), .Names = c("algo", "rst", 
    "prec", "rorac", "prPo", "pos"), row.names = c(1L, 6L, 4L, 7L, 
    11L, 2L, 5L, 3L, 10L, 9L, 8L), class = "data.frame"), rst5 = structure(list(
        algo = c("Mean", "gbm2", "gbm1", "GAM3", "GAM2", "ran2", 
        "nai1", "GAM1", "svm2", "ran1", "svm1"), rst = c(52.4, 46.4, 
        31.2, 28.8, 28.2, 26.6, 23.6, 20.6, 14.4, 14, 6.2), prec = c(0.441, 
        0.44, 0.416, 0.403, 0.481, 0.422, 0.519, 0.398, 0.386, 0.39, 
        0.37), rorac = c(23.604, 23.2, 16.421, 12.743, 34.815, 18.095, 
        45.385, 11.381, 8.182, 9.091, 3.584), prPo = c(92.9, 83.7, 
        79.5, 94.6, 47.1, 61.5, 30.2, 75.7, 73.6, 64.4, 72.4), pos = c(239L, 
        239L, 239L, 239L, 172L, 239L, 172L, 239L, 239L, 239L, 239L
        )), .Names = c("algo", "rst", "prec", "rorac", "prPo", "pos"
    ), row.names = c(1L, 7L, 6L, 5L, 4L, 11L, 2L, 3L, 9L, 10L, 8L
    ), class = "data.frame")), .Names = c("rst1", "rst5")), T0 = structure(list(
        rst1 = structure(list(algo = c("Mean", "ran1", "GAM1", "GAM2", 
        "gbm1", "svm1", "nai1", "gbm2", "svm2", "ran2"), rst = c(22.6, 
        19.4, 13.6, 10.2, 9.6, 8, 5.6, 3.4, -0.4, -0.6), prec = c(0.478, 
        0.452, 0.5, 0.421, 0.423, 0.833, 0.429, 0.373, 0.355, 0.356
        ), rorac = c(33.731, 26.575, 40, 17.895, 18.462, 133.333, 
        20, 4.533, -0.526, -0.368), prPo = c(34.4, 52.1, 24.3, 40.7, 
        37.1, 3.1, 14.4, 53.6, 54.3, 116.4), pos = c(195L, 140L, 
        140L, 140L, 140L, 195L, 195L, 140L, 140L, 140L)), .Names = c("algo", 
        "rst", "prec", "rorac", "prPo", "pos"), row.names = c(1L, 
        9L, 3L, 4L, 5L, 7L, 2L, 6L, 8L, 10L), class = "data.frame"), 
        rst5 = structure(list(algo = c("gbm1", "ran1", "Mean", "GAM1", 
        "GAM2", "svm1", "nai1", "svm2", "gbm2", "ran2"), rst = c(17.6, 
        16.4, 15, 12.8, 9, 6.2, 5.8, -2.6, -3, -9.2), prec = c(0.466, 
        0.434, 0.435, 0.5, 0.41, 0.8, 0.44, 0.346, 0.345, 0.337), 
            rorac = c(30.345, 21.579, 21.739, 40, 14.754, 124, 23.2, 
            -3.21, -3.448, -5.542), prPo = c(41.4, 54.3, 35.4, 22.9, 
            43.6, 2.6, 12.8, 57.9, 62.1, 118.6), pos = c(140L, 140L, 
            195L, 140L, 140L, 195L, 195L, 140L, 140L, 140L)), .Names = c("algo", 
        "rst", "prec", "rorac", "prPo", "pos"), row.names = c(5L, 
        9L, 1L, 3L, 4L, 7L, 2L, 8L, 6L, 10L), class = "data.frame")), .Names = c("rst1", 
    "rst5"))), .Names = c("F0", "T0"))

0

ধরা যাক আমরা প্রতিটি উপাদানটির দৈর্ঘ্য গণনা করতে চাই।

mylist <- list(a=1:4,b=2:9,c=10:20)
mylist

$a
[1] 1 2 3 4

$b
[1] 2 3 4 5 6 7 8 9

$c
 [1] 10 11 12 13 14 15 16 17 18 19 20

যদি উদ্দেশ্যটি কেবল ফলাফলগুলির উপাদানগুলিকে লেবেল করা হয় তবে তার lapply(mylist,length)নীচে বা নীচে কাজ করে।

sapply(mylist,length,USE.NAMES=T)

 a  b  c 
 4  8 11 

যদি লক্ষ্যটি ফাংশনের অভ্যন্তরে লেবেলটি ব্যবহার করা হয়, তবে mapply()দুটি বস্তুর উপর লুপ করে দরকারী; তালিকা উপাদান এবং তালিকা নাম।

fun <- function(x,y) paste0(length(x),"_",y)
mapply(fun,mylist,names(mylist))

     a      b      c 
 "4_a"  "8_b" "11_c" 

0

@ ফের্ডিনানড-ক্র্যাফ্ট আমাদের দুর্দান্ত কৌশল দিয়েছে এবং তারপরে আমাদের বলে যে এটি ব্যবহার করা উচিত নয় কারণ এটি অননুমোদিত এবং কর্মক্ষমতা ওভারহেডের কারণে।

আমি প্রথম পয়েন্টটি নিয়ে অনেক তর্ক করতে পারি না তবে আমি লক্ষ্য করতে চাই যে ওভারহেডটি খুব কমই উদ্বেগের বিষয় হওয়া উচিত।

আসুন সক্রিয় ফাংশনগুলি সংজ্ঞায়িত করুন যাতে আমাদের জটিল এক্সপ্রেশনটি কল করতে হবে না parent.frame()$i[]কেবল কেবল .i(), আমরা .n()নামটি অ্যাক্সেস করার জন্যও তৈরি করব , যা বেস এবং পিউরারের উভয় ক্ষেত্রেই (এবং সম্ভবত বেশিরভাগ অন্যান্যও) কাজ করা উচিত।

.i <- function() parent.frame(2)$i[]
# looks for X OR .x to handle base and purrr functionals
.n <- function() {
  env <- parent.frame(2)
  names(c(env$X,env$.x))[env$i[]]
}

sapply(cars, function(x) paste(.n(), .i()))
#>     speed      dist 
#> "speed 1"  "dist 2"

এখন আসুন একটি সাধারণ ক্রিয়াকলাপ যা কোনও ভেক্টরের আইটেমগুলি তাদের সূচকগুলিতে বিভিন্ন পন্থা ব্যবহার করে আটকে দেয় (এই ক্রিয়াকলাপগুলি অবশ্যই ভেক্টরাইজড ব্যবহার করা যেতে পারে paste(vec, seq_along(vec))তবে এটি এখানে বিন্দু নয়)।

আমরা একটি বেঞ্চমার্কিং ফাংশন এবং একটি প্লটিং ফাংশন সংজ্ঞায়িত করি এবং নীচের ফলাফলগুলি প্লট করি:

library(purrr)
library(ggplot2)
benchmark_fun <- function(n){
  vec <- sample(letters,n, replace = TRUE)
  mb <- microbenchmark::microbenchmark(unit="ms",
                                      lapply(vec, function(x)  paste(x, .i())),
                                      map(vec, function(x) paste(x, .i())),
                                      lapply(seq_along(vec), function(x)  paste(vec[[x]], x)),
                                      mapply(function(x,y) paste(x, y), vec, seq_along(vec), SIMPLIFY = FALSE),
                                      imap(vec, function(x,y)  paste(x, y)))
  cbind(summary(mb)[c("expr","mean")], n = n)
}

benchmark_plot <- function(data, title){
  ggplot(data, aes(n, mean, col = expr)) + 
    geom_line() +
    ylab("mean time in ms") +
    ggtitle(title) +
    theme(legend.position = "bottom",legend.direction = "vertical")
}

plot_data <- map_dfr(2^(0:15), benchmark_fun)
benchmark_plot(plot_data[plot_data$n <= 100,], "simplest call for low n")

benchmark_plot(plot_data,"simplest call for higher n")

দ্বারা তৈরি করা হয়েছে 2019-11-15 ডিপেক্স প্যাকেজ (v0.3.0)

প্রথম চার্টের শুরুতে যে ড্রপটি হ'ল ফ্লুক, দয়া করে এটিকে এড়িয়ে যান।

আমরা দেখতে পেয়েছি যে নির্বাচিত উত্তরটি প্রকৃতপক্ষে দ্রুততর, এবং একটি দ্রষ্ট পরিমাণে পুনরাবৃত্তির জন্য আমাদের .i()সমাধানগুলি সত্যই ধীর, নির্বাচিত উত্তরের তুলনায় ওভারহেড ব্যবহারের ওভারহেডের প্রায় 3 গুণ purrr::imap()এবং 30 কে পুনরাবৃত্তির জন্য 25 এমএস পরিমাণ, সুতরাং আমি প্রতি 1000 পুনরাবৃত্তিতে প্রায় 1 এমএস হারাতে, মিলিয়ন প্রতি 1 সেকেন্ড আমার মতে সুবিধার জন্য এটি একটি সামান্য ব্যয়।


-1

শুধু আপনার নিজস্ব কাস্টম lapplyফাংশন লিখুন

lapply2 <- function(X, FUN){
  if( length(formals(FUN)) == 1 ){
    # No index passed - use normal lapply
    R = lapply(X, FUN)
  }else{
    # Index passed
    R = lapply(seq_along(X), FUN=function(i){
      FUN(X[[i]], i)
    })
  }

  # Set names
  names(R) = names(X)
  return(R)
}

তারপরে এটি ব্যবহার করুন:

lapply2(letters, function(x, i) paste(x, i))

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