ডেটা.ফ্রেমগুলির নেস্টেড তালিকা থেকে কলোনামগুলি বের করুন


10

আমার কাছে ডেটা.ফ্রেমসের নেস্টেড তালিকা রয়েছে, সমস্ত ডাটা.ফ্রেমগুলির কলামের নাম পাওয়ার সহজতম উপায় কী?

উদাহরণ:

d = data.frame(a = 1:3, b = 1:3, c = 1:3)

l = list(a = d, list(b = d, c = d))

ফলাফল:

$a
[1] "a" "b" "c"

$b
[1] "a" "b" "c"

$c
[1] "a" "b" "c"

উত্তর:


7

ইতিমধ্যে বেশ কয়েকটি উত্তর রয়েছে। তবে আমাকে অন্য পদ্ধতি ছেড়ে দিন। আমি rapply2()কাঁচা প্যাকেজ ব্যবহার করেছি ।

devtools::install_github('raredd/rawr')
library(rawr)
library(purrr)

rapply2(l = l, FUN = colnames) %>% 
flatten

$a
[1] "a" "b" "c"

$b
[1] "a" "b" "c"

$c
[1] "a" "b" "c"

5

এখানে একটি বেস আর সমাধান।

আপনি আপনার নেস্টেড তালিকা সমতল করতে কাস্টমাইজড ফাংশনটি সংজ্ঞায়িত করতে পারেন (যা কোনও গভীরতার নেস্টেড তালিকাকে ডিল করতে পারে , উদাহরণস্বরূপ, 2 টিরও বেশি স্তরের), অর্থাৎ,

flatten <- function(x){  
  islist <- sapply(x, class) %in% "list"
  r <- c(x[!islist], unlist(x[islist],recursive = F))
  if(!sum(islist))return(r)
  flatten(r)
}

এবং তারপরে নামগুলি অর্জন করতে নিম্নলিখিত কোডটি ব্যবহার করুন

out <- Map(colnames,flatten(l))

যেমন যে

> out
$a
[1] "a" "b" "c"

$b
[1] "a" "b" "c"

$c
[1] "a" "b" "c"

গভীর নেস্টেড তালিকার উদাহরণ Example

l <- list(a = d, list(b = d, list(c = list(e = list(f= list(g = d))))))
> l
$a
  a b c
1 1 1 1
2 2 2 2
3 3 3 3

[[2]]
[[2]]$b
  a b c
1 1 1 1
2 2 2 2
3 3 3 3

[[2]][[2]]
[[2]][[2]]$c
[[2]][[2]]$c$e
[[2]][[2]]$c$e$f
[[2]][[2]]$c$e$f$g
  a b c
1 1 1 1
2 2 2 2
3 3 3 3

এবং আপনি পাবেন

> out
$a
[1] "a" "b" "c"

$b
[1] "a" "b" "c"

$c.e.f.g
[1] "a" "b" "c"

4

এখানে যথাসম্ভব ভেক্টরাইজড করার চেষ্টা করা হচ্ছে,

i1 <- names(unlist(l, TRUE, TRUE))
#[1] "a.a1" "a.a2" "a.a3" "a.b1" "a.b2" "a.b3" "a.c1" "a.c2" "a.c3" "b.a1" "b.a2" "b.a3" "b.b1" "b.b2" "b.b3" "b.c1" "b.c2" "b.c3" "c.a1" "c.a2" "c.a3" "c.b1" "c.b2" "c.b3" "c.c1" "c.c2" "c.c3"
i2 <- names(split(i1, gsub('\\d+', '', i1)))
#[1] "a.a" "a.b" "a.c" "b.a" "b.b" "b.c" "c.a" "c.b" "c.c"

আমরা এখন i2বিন্দুর আগে সমস্ত কিছুর উপর বিভাজন করতে পারি , যা দেবে,

split(i2, sub('\\..*', '', i2))

#    $a
#    [1] "a.a" "a.b" "a.c"

#    $b
#    [1] "b.a" "b.b" "b.c"

#    $c
#    [1] "c.a" "c.b" "c.c"

এগুলি পুরোপুরি পরিষ্কার করার জন্য, আমাদের লুপ শেষ করতে হবে এবং একটি সাধারণ রেজেক্স প্রয়োগ করতে হবে,

 lapply(split(i2, sub('\\..*', '', i2)), function(i)sub('.*\\.', '', i))

যা দেয়,

$a
[1] "a" "b" "c"

$b
[1] "a" "b" "c"

$c
[1] "a" "b" "c"

কোডটি সংক্রামিত হয়েছে

i1 <- names(unlist(l, TRUE, TRUE))
i2 <- names(split(i1, gsub('\\d+', '', i1)))
final_res <- lapply(split(i2, sub('\\..*', '', i2)), function(i)sub('.*\\.', '', i))

3

এটা চেষ্টা কর

d = data.frame(a = 1:3, b = 1:3, c = 1:3)

l = list(a = d, list(b = d, c = d))

foo <- function(x, f){
    if (is.data.frame(x)) return(f(x))
    lapply(x, foo, f = f)
}

foo(l, names)

এখানে ক্রুসটি হ'ল যে data.framesআসলেই বিশেষ তালিকা, তাই কী কী পরীক্ষা করা উচিত তা গুরুত্বপূর্ণ।

ছোট ব্যাখ্যা: এখানে যা করা দরকার তা হ'ল একটি পুনরাবৃত্তি, যেহেতু প্রতিটি উপাদানগুলির সাথে আপনি কোনও ডেটাফ্রেমের দিকে নজর দিতে পারেন, তাই আপনি সিদ্ধান্ত নিতে চান আপনি প্রয়োগ করেছেন namesবা পুনরাবৃত্তির আরও গভীরে গিয়ে fooআবার কল করবেন কিনা you


সমস্যাটি হ'ল foo (এল, নাম) এছাড়াও একটি নেস্টেড তালিকা প্রদান করে
user680111

আমি না। নিশ্চিত নয়, আপনি কী আলাদাভাবে করেছেন।
Georgery

আপনি unlist()শেষে যুক্ত করতে পারেন , তবে আমি নিশ্চিত নই যে আপনি এটি যা চান তা নিশ্চিত কিনা।
Georgery

2

প্রথমে l1 তৈরি করুন, কেবলমাত্র নামগুলি সহ নেস্টেড তালিকা

l1 <- lapply(l, function(x) if(is.data.frame(x)){
  list(colnames(x)) #necessary to list it for the unlist() step afterwards
}else{
  lapply(x, colnames)
})

তারপরে তালিকাভুক্ত করা l1

unlist(l1, recursive=F)

2

এখানে purrrফাংশন map_depthএবং ব্যবহার করার একটি উপায় রয়েছেvec_depth

library(purrr)

return_names <- function(x) {
   if(inherits(x, "list"))
     return(map_depth(x, vec_depth(x) - 2, names))
    else return(names(x))
}

map(l, return_names)

#$a
#[1] "a" "b" "c"

#[[2]]
#[[2]]$b
#[1] "a" "b" "c"

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