একাধিক কলাম বরাদ্দ করুন: = ডেটা.ট্যাবল করে, দলবদ্ধভাবে


130

একাধিক কলাম ব্যবহার করে নিযুক্ত করার সর্বোত্তম উপায় কী data.table? উদাহরণ স্বরূপ:

f <- function(x) {c("hi", "hello")}
x <- data.table(id = 1:10)

আমি এর মতো কিছু করতে চাই (অবশ্যই এই বাক্য গঠনটি ভুল):

x[ , (col1, col2) := f(), by = "id"]

এবং এটি প্রসারিত করার জন্য, আমার একটি ভেরিয়েবল (বলুন col_names) এ সংরক্ষণ করা নাম সহ অনেকগুলি কলাম থাকতে পারে এবং আমি এটি করতে চাই:

x[ , col_names := another_f(), by = "id", with = FALSE]

এরকম কিছু করার সঠিক উপায় কী?


1
দেখে মনে হচ্ছে এটির উত্তর দেওয়া হয়েছে: stackoverflow.com/questions/11308754/…
অ্যালেক্স

অ্যালেক্স, এই উত্তরটি নিকটে তবে by@ ক্রিসটফ_জে বলা ঠিক যেহেতু এটি মিলিয়ে কাজ করছে বলে মনে হচ্ছে না । আপনার প্রশ্নের লিঙ্ক এফআর # 2120 এ যুক্ত হয়েছে " এলএইচএসের = =" এর জন্য = FALSE এর সাথে প্রয়োজনীয় ড্রপ: সুতরাং এটি পুনরায় দেখাতে ভুলবে না।
ম্যাট ডাউলে

স্পষ্টত, f()একাধিক মান ফেরত দেওয়া একটি ফাংশন, আপনার প্রতিটি কলামের জন্য একটি।
স্মি

উত্তর:


161

এটি এখন আর-ফোর্জে v1.8.3 এ কাজ করে। এটি হাইলাইট করার জন্য ধন্যবাদ!

x <- data.table(a = 1:3, b = 1:6) 
f <- function(x) {list("hi", "hello")} 
x[ , c("col1", "col2") := f(), by = a][]
#    a b col1  col2
# 1: 1 1   hi hello
# 2: 2 2   hi hello
# 3: 3 3   hi hello
# 4: 1 4   hi hello
# 5: 2 5   hi hello
# 6: 3 6   hi hello

x[ , c("mean", "sum") := list(mean(b), sum(b)), by = a][]
#    a b col1  col2 mean sum
# 1: 1 1   hi hello  2.5   5
# 2: 2 2   hi hello  3.5   7
# 3: 3 3   hi hello  4.5   9
# 4: 1 4   hi hello  2.5   5
# 5: 2 5   hi hello  3.5   7
# 6: 3 6   hi hello  4.5   9 

mynames = c("Name1", "Longer%")
x[ , (mynames) := list(mean(b) * 4, sum(b) * 3), by = a]
#     a b col1  col2 mean sum Name1 Longer%
# 1: 1 1   hi hello  2.5   5    10      15
# 2: 2 2   hi hello  3.5   7    14      21
# 3: 3 3   hi hello  4.5   9    18      27
# 4: 1 4   hi hello  2.5   5    10      15
# 5: 2 5   hi hello  3.5   7    14      21
# 6: 3 6   hi hello  4.5   9    18      27


x[ , get("mynames") := list(mean(b) * 4, sum(b) * 3), by = a][]  # same
#    a b col1  col2 mean sum Name1 Longer%
# 1: 1 1   hi hello  2.5   5    10      15
# 2: 2 2   hi hello  3.5   7    14      21
# 3: 3 3   hi hello  4.5   9    18      27
# 4: 1 4   hi hello  2.5   5    10      15
# 5: 2 5   hi hello  3.5   7    14      21
# 6: 3 6   hi hello  4.5   9    18      27

x[ , eval(mynames) := list(mean(b) * 4, sum(b) * 3), by = a][]   # same
#    a b col1  col2 mean sum Name1 Longer%
# 1: 1 1   hi hello  2.5   5    10      15
# 2: 2 2   hi hello  3.5   7    14      21
# 3: 3 3   hi hello  4.5   9    18      27
# 4: 1 4   hi hello  2.5   5    10      15
# 5: 2 5   hi hello  3.5   7    14      21
# 6: 3 6   hi hello  4.5   9    18      27

withআর্গুমেন্টটি ব্যবহার করে পুরানো সংস্করণ (সম্ভব হলে আমরা এই যুক্তিটিকে নিরুৎসাহিত করি):

x[ , mynames := list(mean(b) * 4, sum(b) * 3), by = a, with = FALSE][] # same
#    a b col1  col2 mean sum Name1 Longer%
# 1: 1 1   hi hello  2.5   5    10      15
# 2: 2 2   hi hello  3.5   7    14      21
# 3: 3 3   hi hello  4.5   9    18      27
# 4: 1 4   hi hello  2.5   5    10      15
# 5: 2 5   hi hello  3.5   7    14      21
# 6: 3 6   hi hello  4.5   9    18      27

এই উত্তর এবং উদাহরণের জন্য ধন্যবাদ। দু'টি সারি সহ একটি কলামের পরিবর্তে ধীর আউটপুট থেকে প্রতিটি বস্তুর নামের জন্য দুটি কলাম পাওয়ার জন্য আমি কীভাবে নীচের লাইনটি সংশোধন করব? data.table(objectName=ls())[,c("rows","cols"):=dim(get(objectName)),by=objectName](আমি data.table1.8.11 ব্যবহার করছি )
dnlbrky

@dnlbrky dimএকটি ভেক্টরকে এমন রূপান্তর করে যাতে রূপান্তর করতে পারে যে টাইপ listকরতে হবে এটি ঘোরানো উচিত; যেমন [,c("rows","cols"):=as.list(dim(get(objectName))),by=objectNa‌​me]। সমস্যাটি হ'ল as.listকল ওভারহেড এবং ছোট ভেক্টরকে অনুলিপি করে। গ্রুপ সংখ্যা বৃদ্ধির সাথে সাথে দক্ষতা যদি সমস্যা হয় তবে দয়া করে আমাদের জানান।
ম্যাট ডাওল

1
হাই ম্যাট. আপনার দ্বিতীয় কোড ব্লক (উদাহরণস্বরূপ x[,mynames:=list(mean(b)*4,sum(b)*3),by=a,with=FALSE][]) প্রথম উদাহরণটি এখন একটি সতর্কতা ছুড়েছে, তাই সম্ভবত এটি মুছে ফেলবেন? সম্পর্কিত নোটে, কেউ কি পরামর্শ দিয়েছেন যে, এর সাথে options(datatable.WhenJisSymbolThenCallingScope=TRUE)একটি অ্যাসাইনমেন্ট x[,mynames:=list(mean(b)*4,sum(b)*3),by=a]বাস্তবে কাজ করা উচিত? এটি অন্যান্য পরিবর্তনের সাথে সামঞ্জস্যপূর্ণ বলে মনে হচ্ছে, যদিও এটি আমার ধারণা এটি প্রচুর বিদ্যমান ব্যবহারকারীর কোড (?) ভেঙে দিতে পারে।
জোশ ওব্রায়েন

1
@ ফ্যানফ্রান্সিসকো by=aএটি ছাড়া কার্যকর হবে তবে ভিন্ন উত্তর ফিরে আসবে। mean(a)এবং sum(a)দলা প্রতিটি গ্রুপ যখন মধ্যে পুনর্ব্যবহৃত হচ্ছে by=a। ছাড়া by=aএটি শুধু লাঠি meanএবং sumপ্রতিটি কক্ষে মধ্যে সমগ্র কলাম (অর্থাত বিভিন্ন নম্বর) জন্য।
ম্যাট ডাউল

1
@ ম্যাটডোলে যদি আমার ফাংশনটি ইতিমধ্যে তালিকাভুক্ত তালিকাটি ফেরত দেয় তবে কী আমি কি আবার কলামগুলি আবার নাম না দিয়েই ডিটিতে যুক্ত করতে পারি? যেমন এফ <- ফাংশন (এক্স)) তালিকা ("সি" = "হাই", "ডি" = "হ্যালো") x x [, f () দ্বারা = ক] [] দ্বারা নামযুক্ত কলস সহ ফলাফল মুদ্রণ করবে। কীভাবে ফলাফলটি সংযুক্ত করতে হবে তা আমি জানিনা।
Jfly

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