2017-09-25 9 views
2

私は.csvファイルから読み込まれ、このようになります。データフレームがあります。データフレーム

   job name `phone number` 
      <chr> <chr>   <int> 
1  developer john   654 
2  developer mike   321 
3  developer albert   987 
4  manager dana   741 
5  manager  guy   852 
6  manager anna   936 
7  developer  dan   951 
8  developer shean   841 
9 administrative rebeca   357 
10 administrative krissy   984 
11 administrative hilma   651 
12 administrative otis   325 
13 administrative piper   654 
14  manager mendy   984 
15  manager corliss   321 

DT = structure(list(job = c("developer", "developer", "developer", 
"manager", "manager", "manager", "developer", "developer", "administrative", 
"administrative", "administrative", "administrative", "administrative", 
"manager", "manager"), name = c("john", "mike", "albert", "dana", 
"guy", "anna", "dan", "shean", "rebeca", "krissy", "hilma", "otis", 
"piper", "mendy", "corliss"), phone = c(654L, 321L, 987L, 741L, 
852L, 936L, 951L, 841L, 357L, 984L, 651L, 325L, 654L, 984L, 321L 
)), .Names = c("job", "name", "phone"), row.names = c(NA, -15L 
), class = "data.frame") 

私は、たとえば、どこで、リストのリストに変換したい:

myList$developer 

は私にすべての開発者を含むリストを与えるだろうし、その後

myList$developer$john 

は私に関連付けられている電話番号のリストを与えるだろうジョンという名前の開発者とそれを行う簡単な方法はありますか?

なぜ私はそのようなことをしたいと思うのですか?私が実際に使っているデータフレームは巨大なので、4つのパラメータで特定のエントリを見つけることができます(この例では、 2つのパラメータ(ジョブ、名前)を持つ特定のエントリは、フィルタを使用するのに時間がかかりすぎます。私は、ネストされたリストのハッシュテーブル構造は構築するのに時間がかかるかもしれないと思うが、O(1)では検索可能である。 私が間違っていて、あなたがそれをやるより良い方法を持っているなら、私もそれを聞きたいです。

+0

'lapply(split(df、df $ job)、function(x)split(x $ phone_number、x $ name))'はそれを行います。 –

+0

@AndrewGustarそれは私の答えと同じです;-) – Jaap

答えて

2

ダブルsplitlapplyとし、drop = TRUEのパラメータを使用できます。 drop = TRUEを使用すると、発生しないレベルが削除され、空のリスト要素が作成されなくなります。

使用:

l <- split(dat, dat$job, drop = TRUE) 
nestedlist <- lapply(l, function(x) split(x, x[['name']], drop = TRUE)) 

それとも一度に:

nestedlist <- lapply(split(dat, dat$job, drop = TRUE), 
        function(x) split(x, x[['name']], drop = TRUE)) 

が与える:

> nestedlist 
$administrative 
$administrative$hilma 
       job name phonenumber 
11 administrative hilma   651 

$administrative$krissy 
       job name phonenumber 
10 administrative krissy   984 

$administrative$otis 
       job name phonenumber 
12 administrative otis   325 

$administrative$piper 
       job name phonenumber 
13 administrative piper   654 

$administrative$rebeca 
      job name phonenumber 
9 administrative rebeca   357 


$developer 
$developer$albert 
     job name phonenumber 
3 developer albert   987 

$developer$dan 
     job name phonenumber 
7 developer dan   951 

$developer$john 
     job name phonenumber 
1 developer john   654 

$developer$mike 
     job name phonenumber 
2 developer mike   321 

$developer$shean 
     job name phonenumber 
8 developer shean   841 


$manager 
$manager$anna 
     job name phonenumber 
6 manager anna   936 

$manager$corliss 
     job name phonenumber 
15 manager corliss   321 

$manager$dana 
     job name phonenumber 
4 manager dana   741 

$manager$guy 
     job name phonenumber 
5 manager guy   852 

$manager$mendy 
     job name phonenumber 
14 manager mendy   984 

使用するデータ:

dat <- structure(list(job = c("developer", "developer", "developer", "manager", "manager", "manager", "developer", "developer", "administrative", "administrative", "administrative", "administrative", "administrative", "manager", "manager"), 
         name = c("john", "mike", "albert", "dana", "guy", "anna", "dan", "shean", "rebeca", "krissy", "hilma", "otis", "piper", "mendy", "corliss"), 
         phonenumber = c(654L, 321L, 987L, 741L, 852L, 936L, 951L, 841L, 357L, 984L, 651L, 325L, 654L, 984L, 321L)), 
       .Names = c("job", "name", "phonenumber"), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15")) 
5

私が働いている実際のデータフレームは、私は2つのパラメータで特定のエントリを見つけることができます。この例では4つのパラメータによって特定のエントリ(発見、巨大である:仕事をし、名前)フィルタを使用するには時間がかかりすぎます。私は、ネストされたリストのハッシュテーブル構造は構築するのに時間がかかるかもしれないと思うが、O(1)では検索可能である。私が間違っていて、あなたがそれをやるより良い方法を持っているなら、私もそれを聞きたいです。

明らかに名前検索behaves like O(n), not O(1)

おそらく、より良い方法は、バイナリ検索を使用するdata.tableを使用することです。

library(data.table) 
setDT(DT, key = c("job", "name")) 

get_phones = function(..., d = DT) d[list(...), phone] 

使用例

get_phones("developer", "john") 
# [1] 654 

get_phones("administrative") 
# [1] 651 984 325 654 357 

参照vignette("datatable-keys-fast-subset")又は(おそらくは時代遅れ)copy online

+1

はタイトルとして質問に答えているわけではないので、解決策としてマークしませんが、私のニーズにはより適していました。どうもありがとう! – shayelk