2016-09-02 13 views
3

私はいくつかのデータのために二重ネスト構造を作成しました。どのように私は2番目のレベルのデータにアクセスすることができます(またはそのことについては、n番目のレベルを?)Rのネストされたリストにアクセス

library(gapminder) 
library(purrr) 
library(tidyr) 
gapminder 
nest_data <- gapminder %>% group_by(continent) %>% nest(.key = by_continent) 

nest_2<-nest_data %>% mutate(by_continent = map(by_continent, ~.x %>% group_by(country) %>% nest(.key = by_country))) 

どのように私は今nest_2からのデータフレームまたはtibbleに中国のためのデータを得ることができますか?

私はすべてのアジアのデータを取得できますが、中国を分離することはできません。

a<-nest_2[nest_2$continent=="Asia",]$by_continent ##Any better way of isolating Asia from nest_2? 

は、私はその後、

b<-a[a$country=="China",]$by_country 

を行うことができると思った。しかし、私は次のようなエラーにだから私の大きな誤差は製品がリストである可能性がありましたことを認識していなかった

Error in a[a$country == "China", ] : incorrect number of dimensions 



> glimpse(a) 
List of 1 
$ :Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 33 obs. of 2 variables: 
    ..$ country : Factor w/ 142 levels "Afghanistan",..: 1 8 9 19 25 56 59 60 61 62 ... 
    ..$ by_country:List of 33 

を取得します最後に[[1]]を加えることで救済されました。しかし、私は@ Floo0の解決策を非常に気に入っていました。私は、列の列が提供された列と異なる場合に変数の名前を取る関数を提供する自由を取った。

select_unnest <- function(df, listcol, var, var_val){ ###listcol, var and var_val must enclosed by "" 
    df[[listcol]][df[[var]]==var_val][[1]] 
} 

nest_2 %>% select_unnest(listcol = "by_continent", var = "continent", var_val = "Asia") %>% 
    select_unnest(listcol = "by_country", var = "country", var_val = "China") 

答えて

3

これはパイプ可能(%>%)基地Rアプローチ

select_unnest <- function(x, select_val){ 
    x[[2]][x[[1]]==select_val][[1]] 
} 

nest_2 %>% select_unnest("Asia") %>% select_unnest("China") 

タイミング比較している:

Unit: microseconds 

       min  lq  mean median  uq  max neval 
aosmith1 3202.105 3354.0055 4045.9602 3612.126 4179.9610 17119.495 100 
aosmith2 5797.744 6191.9380 7327.6619 6716.445 7662.6415 24245.779 100 
Floo0  227.169 303.3280 414.3779 346.135 400.6735 4804.500 100 
Ben Bolker 622.267 720.6015 852.9727 775.172 875.5985 1942.495 100 

コード:

microbenchmark::microbenchmark(
    {a<-nest_2[nest_2$continent=="Asia",]$by_continent 
    flatten_df(a) %>% 
    filter(country == "China") %>% 
    unnest}, 
    {nest_2 %>% 
     filter(continent == "Asia") %>% 
     select(by_continent) %>% 
     unnest%>% 
     filter(country == "China") %>% 
     unnest}, 
    {nest_2 %>% select_unnest("Asia") %>% select_unnest("China")}, 
    {n1 <- nest_2$by_continent[nest_2$continent=="Asia"][[1]] 
    n2 <- n1 %>% filter(country=="China") 
    n2$by_country[[1]]} 
) 
0

おそらく、[[]]演算子は単純な[]よりもむしろ必要です。

+0

ハズレB <-a [[$国== "中国"、]]で取得するために一緒にフォーム[filter, column][[1]]の呼び出しをチェーンすることができます$ by_country [[a $ country == "China"、]]のエラー:誤った添字の数 – Misha

0

私はpurrrを使っていないので、この奇妙な/深くネストされた何かで終わったのかどうか分かりません(this questionへの同様のアプローチに従っているようです。 )。私はあなたのaはまだ前に平坦化する必要がリストです

n1 <- nest_2$by_continent[nest_2$continent=="Asia"][[1]] 
n2 <- n1 %>% filter(country=="China") 
n2$by_country[[1]] 
2

...中国のためにこの方法をtibbleを抽出することができますが、あなたが何をしようとして行うには良い方法がなければなりませんあなたはもっとやることができます。

あなたは使用することができflatten_dfdplyr::filter、およびunnest

library(dplyr) 

flatten_df(a) %>% 
    filter(country == "China") %>% 
    unnest 

# A tibble: 12 x 5 
    country year lifeExp  pop gdpPercap 
    <fctr> <int> <dbl>  <int>  <dbl> 
1 China 1952 44.00000 556263527 400.4486 
2 China 1957 50.54896 637408000 575.9870 
3 China 1962 44.50136 665770000 487.6740 
4 China 1967 58.38112 754550000 612.7057 
5 China 1972 63.11888 862030000 676.9001 
6 China 1977 63.96736 943455000 741.2375 
7 China 1982 65.52500 1000281000 962.4214 
8 China 1987 67.27400 1084035000 1378.9040 
9 China 1992 68.69000 1164970000 1655.7842 
10 China 1997 70.42600 1230075000 2289.2341 
11 China 2002 72.02800 1280400000 3119.2809 
12 China 2007 72.96100 1318683096 4959.1149 

アジアを引き出し、あなたがリストで作業していない状況で終わるための別の方法。これは後でflattenの必要性を避けるでしょう。

asia = nest_2 %>% 
    filter(continent == "Asia") %>% 
    select(by_continent) %>% 
    unnest 
1

データ。テーブル・ソリューション:

DT <- as.data.table(gapminder) 

#nest data (starting smallest and working up): 
nest_DT <- DT[, list(by_country = list(.SD)), by = .(continent, country)] 
nest_2 <- nest_DT[, list(by_continent = list(.SD)), by = .(continent)] 

我々は今、ネストされた値

nest_2[continent == "Asia", by_continent][[1]] 
       country by_country 
1:  Afghanistan <data.table> 
2:   Bahrain <data.table> 
3:   Bangladesh <data.table> 
4:   Cambodia <data.table> 
5:    China <data.table> 
6: Hong Kong, China <data.table> 
7:    India <data.table> 
8:   Indonesia <data.table> 
9:    Iran <data.table> 
10:    Iraq <data.table> 
11:    Israel <data.table> 
12:    Japan <data.table> 
...    ...   ... 

nest_2[continent == "Asia", by_continent][[1]][country == "China", by_country][[1]] 

    year lifeExp  pop gdpPercap 
1: 1952 44.00000 556263527 400.4486 
2: 1957 50.54896 637408000 575.9870 
3: 1962 44.50136 665770000 487.6740 
4: 1967 58.38112 754550000 612.7057 
5: 1972 63.11888 862030000 676.9001 
6: 1977 63.96736 943455000 741.2375 
7: 1982 65.52500 1000281000 962.4214 
8: 1987 67.27400 1084035000 1378.9040 
9: 1992 68.69000 1164970000 1655.7842 
10: 1997 70.42600 1230075000 2289.2341 
11: 2002 72.02800 1280400000 3119.2809 
12: 2007 72.96100 1318683096 4959.1149 
関連する問題