2017-05-20 4 views
1

S3リスト様オブジェクトを含むデータフレーム(チブル)列に操作を適用して動作させたい列内の各オブジェクトの名前付きアイテムの1つに追加します。質問の一番下にあるように、sapply()mutate()の範囲で使用していますが、これは不要なようです。mutate()でS3リストのようなオブジェクト内の値にアクセスする(S3オブジェクト内から値を抽出する)

情報が原子データを含む列に格納される場合、mutate()のようなdplyr関数は期待どおりに機能します。たとえば、次のように動作します。

library(dplyr) 
people_cols <- tibble(name = c("Fiona Foo", "Barry Bar", "Basil Baz"), 
        height_mm = c(1750, 1700, 1800), 
        weight_kg = c(75, 73, 74)) %>% 
    mutate(height_inch = height_mm/25.4) 
people_cols 
# # A tibble: 3 × 4 
# name   height_mm weight_kg height_inch 
# <chr>   <dbl>  <dbl>  <dbl> 
# 1 Fiona Foo  1750  75   68.89764 
# 2 Barry Bar  1700  73   66.92913 
# 3 Basil Baz  1800  74   70.86614 

しかし、私はS3リストオブジェクトのデータを扱いたいと思います。私はこのようなtibbleの列にこれらのオブジェクトを置くことができます

person_stats <- function(name, height_mm, weight_kg) { 
    this_person <- structure(list(name = name, 
           height_mm = height_mm, 
           weight_kg = weight_kg), 
          class = "person_stats") 
} 

fiona <- person_stats("Fiona Foo", 1750, 75) 
barry <- person_stats("Barry Bar", 1700, 73) 
basil <- person_stats("Basil Baz", 1800, 74) 

fiona$height_mm 
# [1] 1750 

:ここでおもちゃの例である

people <- tibble(personstat = list(fiona, barry, basil)) 

people 
# # A tibble: 3 × 1 
# personstat 
#  <list> 
# 1 <S3: person_stats> 
# 2 <S3: person_stats> 
# 3 <S3: person_stats> 

しかし、私は含む列の上に、私はエラーを取得し、それらのオブジェクトを変異()を使用しようとした場合:

people <- tibble(personstat = list(fiona, barry, basil)) %>% 
    mutate(height_inch = personstat$height_mm/25.4) 
# Error in mutate_impl(.data, dots) : object 'personstat' not found 

できるだけ簡単にそれを維持しようとして - 私も自分で名前の項目を参照することができるならば、私は、少なくとも新しい列にそれらを得ることができ、その後、そこからどんな操作を行うO nはそれら:面白いです

people <- tibble(personstat = list(fiona, barry, basil)) %>% 
    mutate(height_mm = personstat$height_mm) 
# Error in mutate_impl(.data, dots) : 
# Unsupported type NILSXP for column "height_mm" 

注異なるエラー、 - それはもはや単なるという項目に苦しんで、列を見つける文句です。

私は、それがベースの機能を使用して動作する機能として[[cbind()sapply()を取得することができます:

people <- tibble(personstat = list(fiona, barry, basil)) %>% 
    cbind(height_mm = sapply(.$personstat, '[[', name="height_mm")) 

people 
#   personstat height_mm 
# 1 Fiona Foo, 1750, 75  1750 
# 2 Barry Bar, 1700, 73  1700 
# 3 Basil Baz, 1800, 74  1800 

ことがtibble-inessを失うけれども。

class(people) 
# [1] "data.frame" 

そして最後に、働く、これに私を得たが、それは私がそれを必要とせずにすべての方法の列ダウン動作するはずだと思うミスのsapply()一種dplyr mutate()のポイント、使用してのように感じている:

people <- tibble(personstat = list(fiona, barry, basil)) %>% 
    mutate(height_mm = sapply(.$personstat, '[[', name="height_mm")) 
people 
# A tibble: 3 x 2 
#   personstat height_mm 
#    <list>  <dbl> 
# 1 <S3: person_stats>  1750 
# 2 <S3: person_stats>  1700 
# 3 <S3: person_stats>  1800 

sapply()のようなものに依存することなく、上記のような出力を得るためにmutate()を使用する方法はありますか?または、実際には、チブルの列に格納されたリストのようなS3オブジェクトから名前付き値を抽出する他の賢明な方法はありますか?あなたはtidyverseでそれを維持したい場合

答えて

2

rowwiseは、このようなケースを扱うことができます。このため

people <- tibble(personstat = list(fiona, barry, basil)) 

people %>% 
    rowwise() %>% 
    mutate(height_mm = personstat$height_mm) 
# # A tibble: 3 × 2 
#   personstat height_mm 
# <list>  <dbl> 
# 1 <S3: person_stats>  1750 
# 2 <S3: person_stats>  1700 
# 3 <S3: person_stats>  1800 

people %>% 
    rowwise() %>% 
    mutate(height_inch = personstat$height_mm/25.4) 

# # A tibble: 3 × 2 
#   personstat height_inch 
# <list>  <dbl> 
# 1 <S3: person_stats> 68.89764 
# 2 <S3: person_stats> 66.92913 
# 3 <S3: person_stats> 70.86614 
+0

ありがとう。私は 'rowwise()'を意識することはできませんでしたが、ちょうど仕事のように見えます。しかし、私はあなたが示唆していることを行ういくつかのエラーを取得しています。一番上のバージョンは動作しますが、 'height_inch ='計算のバージョンはエラーを投げます。私はdplyr v0.5.0(CRANの最新版)を使用しています。残念ながら、現時点でGitHubのバージョンはインストールされていません。おそらくあなたは新しい/開発版を使用していますか? – jamse

+0

エラーメッセージは 'Error in mutate_impl(.data、dots):オブジェクト 'personstat' not found'です。 – jamse

+0

@jamse、私は上記のコードでdplyr 0.6.0プレリリース(githubから入手可能)を使用します。 v0.5.0でも同じエラーが表示されます。 v0.5.0のバグかもしれません。私はわかりません。 – mt1022

1

あなたはここにpurrr::map_dblを使用することができます。

library(tidyverse)  
people %>% mutate(height = map_dbl(personstat, "height_mm")) 
+1

感謝を。私はそれがちょうどdplyrであり、私の目には少しはっきりしているので、他の答えを受け入れましたが、これもうまくいきます。 'map_dbl'バージョンを使いたい人は、計算を行いたいだけでなく、変数を抽出したいなら、map_dblの呼び出しの外にそれを含めることができます:' people%>%mutate(height_inch = map_dbl(personstat、高さmm)/ 25。4) ' – jamse

関連する問題