6

一部のデータに対して二重にネストされた構造を作成しました。第 2 レベルのデータにアクセスするにはどうすればよいですか (または、n 番目のレベルについてはどうすればよいでしょうか?)

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 からデータフレームまたはティブルに取得するにはどうすればよいですか?

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

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")
4

5 に答える 5

4

これは、パイプ可能な ( %>%) ベース 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]]}
)
于 2016-09-02T15:08:37.647 に答える
1

data.table ソリューション:

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

フォームの呼び出しを連鎖させ[filter, column][[1]]て、ネストされた値を取得できるようになりました

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
于 2016-09-02T17:31:55.140 に答える
1

私は使用purrrしないので、どのようにしてこの奇妙な/深くネストされたものになったのかよくわかりません(この質問に対して同様のアプローチに従っているようです;その質問に対するコメントは、いくつかの代替アプローチを示唆しています)。この方法で中国のことを抽出できますが、あなたがやろうとしていることを行うためのより良い方法があるに違いありません...

n1 <- nest_2$by_continent[nest_2$continent=="Asia"][[1]]
n2 <- n1 %>% filter(country=="China")
n2$by_country[[1]]
于 2016-09-02T13:27:23.160 に答える
0

おそらく必要なのは、単純な単一の [] の代わりに [[]] 演算子です。

于 2016-09-02T13:20:20.310 に答える