2017-01-17 4 views
-1

から値を置き換える...purrrループ1つのデータフレームの列を通って、条件付きで、以下のデータを持つ別のデータフレーム

library(tidyverse) 

df_fac <- data_frame("author_1" = c("Ted", "Fred", NA, "Jim", "Tim"), 
       "role_1" = c("Faculty", "Faculty", "Staff", "Faculty", "Faculty"), 
       "author_2" = c(NA, "Will", NA, "Bill", NA), 
       "role_2" = c("Staff", "Faculty", "Staff", "Faculty", "Staff")) 

df_all <- data_frame("author_1" = c("Ted", "Fred", "Simon", "Jim", "Tim"), 
        "role_1" = c("Faculty", "Faculty", "Staff", "Faculty", "Faculty"), 
        "author_2" = c("Sam", "Will", "Noah", "Bill", "Luther"), 
        "role_2" = c("Staff", "Faculty", "Staff", "Faculty", "Staff")) 

df_facで「作者」の列がNAであれば、私はでいっぱいにするためにそれらをしたいと思います対応する列の値は、からmapの関数を使用してpurrrになります。これは、私は現在、ループせずに何をすべきかです:map_df

df_test <- df_fac %>% 
    mutate(`author_1` = ifelse(is.na(`author_1`), df_all$`author_1`, `author_1`)) %>% 
    mutate(`author_2` = ifelse(is.na(`author_2`), df_all$`author_2`, `author_2`)) 

私はdf_facの列に対するこの反復処理を行うことができますが、ないdf_allに(あなたが見ることができるようにそれが唯一の著者欄1です)。

df_test <- map_df(select(df_fac, matches("author.\\d$")), ~ { 
    ifelse(is.na(.), df_all$`author_1`, .) 
}) 

それはselect(df_fac, matches("author.\\d$"))にわたり反復しながらselect(df_all, matches("author.\\d$"))オーバーmap_df反復を持ってする方法はありますか?

おもちゃの例では、df_testは、同じ著者の列と値がdf_allである必要があります。私が試してみました:

df_test <- map_df(1:length(select(df_fac, matches("author.\\d$"))), ~ { 
    ifelse(is.na(select(df_fac, matches("author.\\d$"))[.]), 
    select(df_all, matches("author.\\d$"))[.], 
    select(df_fac, matches("author.\\d$"))[.]) 
}) 

Error in bind_rows_(x, .id) : not compatible with STRSXP

df_test <- pmap_chr(list(is.na(select(df_fac, matches("author.\\d$"))), 
         select(df_all, matches("author.\\d$")), 
         select(df_fac, matches("author.\\d$"))), 
        ifelse) 

は、私は、実際のデータは、同様の変数名で混合著者のコラムをたくさん持っているようmatches機能を使用する必要がError: Element 2 has length 2, not 1 or 10.

をスロースローします。これが明確でないかどうかを明確にすることができます。ありがとうございました。

+0

この例では、 'df_test'の出力を' df_all'と同じにしたいと思われます。実際のデータをよりよく反映させるために改善することができますか?その問題は何ですか?また: 'マップ'は素晴らしいですが、それはあなたのニーズに合っていると確信していますか?たぶん '* _join()'やその他のものがより適切でしょう –

+0

@apom 2つの 'mutate'呼び出しを持つコードチャンクは、まさに私がやろうとしているのですが、ループを使用しています。実際のデータには、 'df_all'にはない' df_fac'に列と値があります。逆の場合もあります。上の例では、著者名が不足している必要があります。私が今やっているやり方にはまったく問題はありません。繰り返しコードがたくさんあります(私は他のいくつかの変数を使って同じことをしていますが、これは約24の非常によく似たmutate呼び出しです)。 – Tunn

+0

もう一度質問します。 'df_fac'と' df_all'は同じ順序であると安全に仮定できますか?何とか 'cbind()'すれば、その行は常に一致しますか?または、参加する変数がありますか? –

答えて

2

map2_dfを使用すると、2つのリストを同時にループすることができます。 dplyr::coalseceを使用すると、欠損値の置き換えに役立ちます。 df_allの列がdf_facと同じ順番であることを確認するためにselectを使用しました。

map2_df(df_fac, select(df_all, one_of(names(df_fac))), ~coalesce(.x, .y)) 

同じことpmapを使用して:

pmap_df(list(df_fac, select(df_all, one_of(names(df_fac)))), coalesce) 

をあなたが使用している2つの異なるリストを参照するために式表記と一緒に、同様に、map2ifelseを使用することができます。

map2_df(df_fac, select(df_all, one_of(names(df_fac))), 
     ~ifelse(is.na(.x), .y, .x)) 
+0

これはかなり素晴らしいです。オリジナルのデータでいくつかのサブセットを作成しなければなりませんでしたが、これは素晴らしい解決策です。 'map2'レッスンをありがとう。 – Tunn

関連する問題