2017-12-15 11 views
1

私は、各チェックボックスがインジケータ変数であるアンケートから非常に面倒なデータセットを持っています。したがって、エントリとしてM/Fの変数として性別(または競争)を持たせる代わりに、指標を持つgender_m列とgender_f列があります。列名を変数に整理する

簡体例:

df <- tribble(
    ~id, ~gender_m, ~gender_f, 
    #--|----------|--------- 
    1L , 0  , 1, 
    2L , 1  , 0, 
    3L , 0  , 0, 
    4L , 1  , 1 
) 

出力があると私は何をしたいこと:

性別のようなもののためにのみ2列がある、それはハードコードのものに十分に簡単ですが、私はレース(または使用するプログラミング言語)などのものは複数の可能性があるため、できるだけジェネリックにしようとしています。

私は約1000の列ですが、実際の変数は20未満です。すべての列の形式は<variable_name>_<potential_value>です。

私はこれを行うきちんとした機能が不足していると確信していますが、私のgooglefuは今日は弱いようです。

+0

"欠けている"と "1つ以上の選択された"は、これをかなり特殊化しています - あなたは存在する機能を見つけることに失敗しているとは思わない。 – Gregor

答えて

5

tidy機能の多くは、行よりも列に良い仕事なので、あなたが長い間に変換する場合、これは少し楽になり:

df_long = df %>% 
    gather(Item, Response, starts_with("gender")) 

cleaned = df_long %>% 
    mutate(Item = str_match(Item, "(.*)_(.*)")[, 3]) %>% 
    group_by(id) %>% 
    summarize(RespCleaned = case_when(
     sum(Response) == 0 ~ "Missing", 
     sum(Response) == 1 ~ Item[Response == 1][1], 
     sum(Response) > 1 ~ "More than 1 selected" 
    )) 

df = df %>% left_join(cleaned, by = "id") 

あなたは0/1指標のこれらの種類のアイテムをたくさん持っている場合レスポンスの合計を使用すると、2つ以上のオプションを持つアイテムに一般化する必要があります。 starts_with("gender")を関連する列を選択するのではなく、別のセレクターに置き換えるだけで済みます。

1

ここには基本的なアプローチがあります(stringrを除く)。同様のケースにうまく行き渡って、機能に入れ易くするべきです。そのままでは、1000列の20個の変数で、データフレーム全体を操作できます。

library(stringr) 
sep = "_" 
vars = unique(na.omit(str_extract(names(df), ".*(?=_)"))) 

for (i in seq_along(vars)) { 
    these_vars = names(df)[str_detect(names(df), paste0("^", vars[i]))] 
    result = character(nrow(df)) 
    rs = rowSums(df[these_vars]) 
    result[rs == 0] = "mising" 
    result[rs > 1] = "more than 1 selected" 
    result[rs == 1] = these_vars[apply(df[rs == 1, these_vars] == 1, 1, which)] 
    df[i] = result 
} 

df 
# # A tibble: 4 x 4 
#  id gender_m gender_f    gender 
# <int> <dbl> <dbl>    <chr> 
# 1  1  0  1    gender_f 
# 2  2  1  0    gender_m 
# 3  3  0  0    mising 
# 4  4  1  1 more than 1 selected 
関連する問題