R мутировать() с суммами строк()

#r #sum #rowsum

Вопрос:

Я хочу взять фрейм данных идентификаторов участников и языков, на которых они говорят, а затем создать новый столбец, в котором суммируются все языки, на которых говорит каждый участник. Столбцы-это идентификатор, каждый язык с 0 = «не говорит» и 1 = «говорит», включая столбец «Другое», затем отдельный столбец, в котором указывается, что это за другой язык, «Другой.Lang». Я хочу подмножествовать только столбцы с двоичными значениями и создать этот новый столбец с суммами для каждого участника.

Сначала вот мой фрейм данных.

   Participant.Private.ID French Spanish Dutch Czech Russian Hebrew Chinese German Italian Japanese Korean Portuguese Other Other.Lang  1 5133249 0 0 0 0 0 0 0 0 0 0 0 0 0 0  2 5136082 0 0 0 0 0 0 0 0 0 0 0 0 0 0  3 5140442 0 1 0 0 0 0 0 0 0 0 0 0 0 0  4 5141991 0 1 0 0 0 0 0 0 1 0 0 0 0 0  5 5143476 0 0 0 0 0 0 0 0 0 0 0 0 0 0  6 5145250 0 0 0 0 0 0 0 0 0 0 0 0 1 Malay  7 5146081 0 0 0 0 0 0 0 0 0 0 0 0 0 0   

Вот структура:

   str(part_langs)    grouped_df [7 x 15] (S3: grouped_df/tbl_df/tbl/data.frame)  $ Participant.Private.ID: num [1:7] 5133249 5136082 5140442 5141991 5143476 ...  $ French : num [1:7] 0 0 0 0 0 0 0  $ Spanish : num [1:7] 0 0 1 1 0 0 0  $ Dutch : num [1:7] 0 0 0 0 0 0 0  $ Czech : num [1:7] 0 0 0 0 0 0 0  $ Russian : num [1:7] 0 0 0 0 0 0 0  $ Hebrew : num [1:7] 0 0 0 0 0 0 0  $ Chinese : num [1:7] 0 0 0 0 0 0 0  $ German : num [1:7] 0 0 0 0 0 0 0  $ Italian : num [1:7] 0 0 0 1 0 0 0  $ Japanese : num [1:7] 0 0 0 0 0 0 0  $ Korean : num [1:7] 0 0 0 0 0 0 0  $ Portuguese : num [1:7] 0 0 0 0 0 0 0  $ Other : num [1:7] 0 0 0 0 0 1 0  $ Other.Lang : chr [1:7] "0" "0" "0" "0" ...  - attr(*, "groups")= tibble [7 x 2] (S3: tbl_df/tbl/data.frame)  ..$ Participant.Private.ID: num [1:7] 5133249 5136082 5140442 5141991 5143476 ...   

Я думал, что это должно сработать:

   num lt;- part_langs %gt;%  mutate(num.langs = rowSums(part_langs[2:14]))  num   

Однако я продолжаю получать это сообщение об ошибке:

   Error: Problem with `mutate()` input `num.langs`.  x Input `num.langs` can't be recycled to size 1.  i Input `num.langs` is `rowSums(part_langs[2:14])`.  i Input `num.langs` must be size 1, not 7.  i The error occurred in group 1: Participant.Private.ID = 5133249.   

What is really strange is that when I try to create a simplified version of this problem to create a reproducible example, it works fine.

First I create a dataset.

   test lt;- matrix(c(1, 1, 1, 0, 0, "",  2, 1, 0, 1, 0, "",  3, 0, 0, 0, 1, "Chinese"), ncol = 6, byrow=TRUE)    testlt;-as.data.frame(test)    colnames(test) lt;- c("ID", "English", "French", "Italian", "Other", "Other.Lang")    str(test)   

Преобразование двоичных столбцов в числовые:

   test$ID lt;- as.numeric(test$ID)  test$English lt;- as.numeric(test$English)  test$French lt;- as.numeric(test$French)  test$Italian lt;- as.numeric(test$Italian)  test$Other lt;- as.numeric(test$Other)   

Вот тот же код, что и выше, но с этим упрощенным набором данных.

   num lt;- test %gt;%  mutate(num.langs = rowSums(test[2:5]))  num   

Вот результат. Это работает именно так, как я хочу:

   "ID","English","French","Italian","Other","Other.Lang","num.langs"  1, 1, 1, 0, 0, "", 2  2, 1, 0, 1, 0, "", 2  3, 0, 0, 0, 1, "Chinese", 1   

Поэтому я знаю, что где-то напортачил с моими реальными данными, но не могу понять, где именно. Может ли кто-нибудь посоветовать?

Комментарии:

1. Разница в результате может быть связана с тем, что part_langs это grouped_df [7 x 15] (S3: grouped_df/tbl_df/tbl/data.frame) так . Может ungroup быть , вот так: library(dplyr); part_langs lt;- part_langs %gt;% ungroup ?

2. Или избегайте использования мутировать и и попробуйте part_langs$num.langs = rowSums(part_langs[2:14])

3. @ChrisRuehlemann Ты был прав! Добавление кода разгруппировки и его повторный запуск устраняют эту проблему. Большое спасибо!

4. @Dave2e Вы абсолютно правы, это, безусловно, самый разумный способ подойти к этому…но я был разочарован тем, что не знал, почему mutate() работает не так, как я думал, и я должен был сначала это понять. Я тоже ценю ваше предложение.

5. Если это помогло, я собираюсь добавить этот комментарий в качестве ответа, надеясь, что вы примете/поддержите его!

Ответ №1:

Разница в результате может быть связана с тем, что part_langs это сгруппированный фрейм данных, как видно из вывода str , показанного в вашем посте:

 grouped_df [7 x 15] (S3: grouped_df/tbl_df/tbl/data.frame).   

Если это причина, то ungroup сначала и повторите свой код:

 library(dplyr) part_langs lt;- part_langs %gt;% ungroup  

Ответ №2:

Другой подход, на который больше полагается dplyr , заключался бы в использовании rowwise и c_across :

 test %gt;%  rowwise() %gt;%  mutate(num.lang = sum(c_across(English:Other)))