2017-08-30 12 views
1

dplyrbind_rows機能が好きですが、.id引数を渡すときには、新しい列に数値インデックスを追加するだけで済みます。オブジェクト名へのアクセスとバインディングR

私はbind_rows_named関数を記述しようとしていますが、オブジェクト名にアクセスできません。

bind_name_to_df <- function(df){ 
    dfname <- deparse(substitute(df)) 
    df %>% mutate(label=dfname) 
} 

a <- data_frame(stuff=1:10) 
bind_name_to_df(a) 

しかし、私は、例えば、データフレームのリストにこれを適用する方法を考え出すことはできません。期待通りこれは動作しますドットを使って。私はこれを動作させるが、私は何かを間違って...のセマンティクスがあることを知っている。誰も光を放つことができますか?ここで

b <- data_frame(stuff=1:10) 

bind_rows_named <- function(...){ 
    return(
    bind_rows(lapply(..., bind_name_to_df))) 
} 

bind_rows_named(a, b) 
+2

他の文脈では、私は便利な関数 'Hmisc :: llist'を" listのように "使用しました。変数 'label'属性のコンポーネント変数です。"したがって、ここで 'bind_rows(Hmisc :: llist(a、b)、.id =" label ")' – Henrik

+1

があります。オブジェクト名?](https://stackoverflow.com/questions/16951080/can-lists-be-created-that-name-themselves-based-on-input-object-names) – Henrik

+1

'.id'からのラベルは'bind_rows'に名前付き引数を与えないと、整数だけを返します。 'bind_rows(a = .a =" label ")'を参照してください。これは 'Hmisc :: llist'を作るのに便利な名前付きリストを持っているときにうまくいきます。 – aosmith

答えて

1

base R

bind_named <- function(...){ 
    v1 <- sapply(match.call()[-1], deparse) 
    dfs <- list(...) 
    Map(cbind, dfs, label = v1) 

    } 

bind_named(a, b) 
#[1]] 
# stuff label 
#1  1  a 
#2  2  a 
#3  3  a 
#4  4  a 
#5  5  a 
#6  6  a 
#7  7  a 
#8  8  a 
#9  9  a 
#10 10  a 

#[[2]] 
# stuff label 
#1  1  b 
#2  2  b 
#3  3  b 
#4  4  b 
#5  5  b 
#6  6  b 
#7  7  b 
#8  8  b 
#9  9  b 
#10 10  b 

か、単鎖

にもを行うことができます tidyverse

library(tidyverse) 
bind_named <- function(...) { 
nm1 <- quos(...) %>% 
      map(quo_name) 
dfs <- list(...) 
dfs %>% 
    map2(nm1, ~mutate(., label = .y)) 
    } 

res <- bind_named(a, b) 
res %>% 
    map(head, 2) 
#[[1]] 
# stuff label 
#1  1  a 
#2  2  a 

#[[2]] 
# stuff label 
#1  1  b 
#2  2  b 

を使用してを使用してオプションです

bind_named <- function(...) { 
    quos(...) %>% 
    map(quo_name) %>% 
    map2_df(list(...), ., ~mutate(.data = .x, label = .y)) 
    } 

bind_named(a, b) 
# A tibble: 20 x 2 
# stuff label 
# <int> <chr> 
# 1  1  a 
# 2  2  a 
# 3  3  a 
# 4  4  a 
# 5  5  a 
# 6  6  a 
# 7  7  a 
# 8  8  a 
# 9  9  a 
#10 10  a 
#11  1  b 
#12  2  b 
#13  3  b 
#14  4  b 
#15  5  b 
#16  6  b 
#17  7  b 
#18  8  b 
#19  9  b 
#20 10  b 

注:当初OPは別々のデータセットに列を作成し、listの出力を得たいと考えました。明確化すると、map2map2_dfに変更され、単一のデータセットを返します

+1

@bjwさて、あなたの関数の 'bind_rows'と混乱しました。私はあなたが列を作成したいと思った。単一のデータセットが必要な場合は、 'map2'を' map2_df'に変更してください。 (最後の機能が変更されたときのように) – akrun

関連する問題