2017-01-16 3 views
1

У меня есть данные на уровне пользователя, который выглядит следующим образом:Динамически создавать переменные на основе двоичных индикаторов в R

ID V1 V2 V3 V4 
001 1 0 1 0 
002 0 1 0 1 
003 0 0 0 0 
004 1 1 1 0 

В приведенном выше примере, я хотел бы элегантное решение (скорее всего, с помощью tidyr) динамически реорганизовать это выглядеть так:

ID Num_Vars Var1 Var2 Var3 
001 2  V1 V3 NA 
002 2  V2 V4 NA 
003 0  NA NA NA 
004 3  V1 V2 V3 

Обратите внимание, что этот пример упрощен и есть на самом деле много переменных. Дело в том, чтобы иметь код, который определяет, сколько переменных должно быть создано, на основе максимального количества 1s в Var1-VarX, которые заполняются для любого пользователя.

+1

Извините @hrbrmstr Я потратил несколько часов на это пару недель назад и отказался от него, но потом решил вместо этого сделать учетную запись StackOverflow (новичок в этом). Я пытался собраться и распространиться (и некоторые глупые попытки на петли), но пропуская шаги между ними. PS наслаждался разговором на конференции RStudio! –

ответ

5

Это чувствует, как некоторые довольно стандартной перепрофилирования: преобразовать долго, манипулировать группой, конвертировать обратно в широка:

df %>% 
    gather(key = var, value = value, -ID) %>% 
    group_by(ID) %>% 
    filter(value != 0) %>% 
    mutate(Num_Vars = n(), 
      Var_Label = paste0("Var", 1:n())) %>% 
    spread(key = Var_Label, value = var) %>% 
    select(-value) %>% 
    full_join(distinct(df, ID)) 
# Source: local data frame [4 x 5] 
# Groups: ID [?] 
# 
#  ID Num_Vars Var1 Var2 Var3 
# <int> <int> <chr> <chr> <chr> 
# 1  1  2 V1 V3 <NA> 
# 2  2  2 V2 V4 <NA> 
# 3  4  3 V1 V2 V3 
# 4  3  NA <NA> <NA> <NA> 

Используя эти данные воспроизводимо совместно с dput():

df = structure(list(ID = 1:4, V1 = c(1L, 0L, 0L, 1L), V2 = c(0L, 1L, 
0L, 1L), V3 = c(1L, 0L, 0L, 1L), V4 = c(0L, 1L, 0L, 0L)), .Names = c("ID", 
"V1", "V2", "V3", "V4"), class = "data.frame", row.names = c(NA, 
-4L)) 
+0

Спасибо, @Gregor. Мне не хватало шагов между вашей сборкой и распространением. Я не могу принять ваш ответ до тех пор, пока не получу репутацию 15 (это был мой первый вопрос), но я обязательно позабочусь об этом! –

+0

Вы можете быть добрыми, чтобы принять сейчас :-) Также: rly приятно сделал пример @gregor. – hrbrmstr

0

Мы можем использовать melt/dcast от data.table

library(data.table) 
dcast(melt(setDT(df), id.var = "ID")[, Num_vars := sum(value), 
    ID][value!=0][df[, "ID", with = FALSE], on = "ID"], 
    ID + Num_vars ~ paste0("Var", rowid(ID)), value.var = "variable") 
# ID Num_vars Var1 Var2 Var3 
#1: 1  2 V1 V3 NA 
#2: 2  2 V2 V4 NA 
#3: 3  NA NA NA NA 
#4: 4  3 V1 V2 V3 
Смежные вопросы