डेटा की एक नेस्टेड सूची से कॉलनामें निकालें


10

मेरे पास data.frames की नेस्टेड सूची है, सभी data.frames के कॉलम नामों को प्राप्त करने का सबसे आसान तरीका क्या है?

उदाहरण:

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"

एक गहरी नेस्टेड सूची के साथ उदाहरण

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फिर से गहराई में जाते हैं और फिर से कॉल करते हैं।


समस्या यह है कि फू (एल, नाम) भी एक नेस्टेड सूची देता है
user680111

मैं नही। यकीन नहीं होता, आपने अलग ढंग से क्या किया।
जॉर्जी

आप unlist()अंत में जोड़ सकते हैं , लेकिन मुझे यकीन नहीं है कि यह वही है जो आप चाहते हैं।
जॉर्जी

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)
})

फिर एल 1 को अनलिस्ट करें

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"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.