Ekstrak nama nama dari daftar data.frame yang bersarang

10

Saya memiliki daftar data.frame, bagaimana cara termudah untuk mendapatkan nama kolom dari semua data.frame?

Contoh:

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

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

Hasil:

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

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

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

Jawaban:

7

Sudah ada beberapa jawaban. Tetapi biarkan saya meninggalkan pendekatan lain. Saya menggunakan rapply2()paket rawr.

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"
jazzurro
sumber
5

Berikut ini adalah solusi R dasar.

Anda dapat mendefinisikan fungsi khusus untuk meratakan daftar bersarang Anda (yang dapat menangani daftar bersarang dari kedalaman apa pun , misalnya, lebih dari 2 level), yaitu,

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

dan kemudian gunakan kode berikut untuk mencapai nama samaran

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

seperti yang

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

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

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

Contoh dengan daftar bersarang yang lebih dalam

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

dan kamu akan mendapatkan

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

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

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

Berikut adalah upaya untuk melakukan ini sebagai Vektor mungkin,

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"

Kita sekarang dapat membagi i2segalanya sebelum titik, yang akan memberi,

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"

Untuk membersihkannya, kita perlu mengulang dan menerapkan regex sederhana,

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

pemberian yang mana,

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

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

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

Kode dipadatkan

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

Coba ini

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)

Intinya di sini adalah bahwa data.framessebenarnya daftar khusus, jadi penting untuk menguji apa.

Penjelasan kecil: apa yang perlu dilakukan di sini adalah rekursi, karena dengan setiap elemen Anda mungkin melihat salah satu kerangka data, jadi Anda ingin memutuskan apakah Anda menerapkan namesatau masuk lebih dalam ke rekursi dan menelepon foolagi.

Georgery
sumber
Masalahnya adalah bahwa foo (l, nama) juga mengembalikan daftar bersarang
user680111
Bukan saya. Tidak yakin, apa yang Anda lakukan berbeda.
Georgery
Anda dapat menambahkan unlist()di akhir, tetapi saya tidak yakin apakah ini yang Anda inginkan.
Georgery
2

Pertama-tama buat l1, daftar bersarang dengan hanya colnames

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

Kemudian hapus daftar l1

unlist(l1, recursive=F)
Solarion
sumber
2

Berikut ini salah satu cara menggunakan purrrfungsi map_depthdanvec_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"
Ronak Shah
sumber