select () преобразованные / новые переменные внутри одного mutate () - PullRequest
2 голосов
/ 06 июня 2019

Рассмотрим ДФ как это:

   colA colB colC colD
1     1   50  100    a
2     2   51  101    b
3     3   52  102    c
4     4   53  103    d
5     5   54  104    e
6     6   55  105    f
7     7   56  106    g
8     8   57  107    h
9     9   58  108    i
10   10   59  109    j

Я хочу преобразовать переменную "colA", а затем вычислить сумму переменных в строке, которую я выберу select() внутри mutate(). Я делаю это:

df %>%
 mutate(colA = colA * 60,
        sum = rowSums(select(., colA, colB, colC)))

, который дает мне неверный результат:

   colA colB colC colD sum
1    60   50  100    a 151
2   120   51  101    b 154
3   180   52  102    c 157
4   240   53  103    d 160
5   300   54  104    e 163
6   360   55  105    f 166
7   420   56  106    g 169
8   480   57  107    h 172
9   540   58  108    i 175
10  600   59  109    j 178

Если я создаю совершенно новую переменную:

df %>%
 mutate(colA_mod = colA * 60,
        sum = rowSums(select(., colA_mod, colB, colC)))

Я получаю:

Ошибка: ошибка оценки: позиция должна быть между 0 и n.

Однако, когда я использую два отдельных mutate() с, я получаю правильные результаты:

df %>%
 mutate(colA = colA * 60) %>%
 mutate(sum = rowSums(select(., colA, colB, colC)))

   colA colB colC colD sum
1    60   50  100    a 210
2   120   51  101    b 272
3   180   52  102    c 334
4   240   53  103    d 396
5   300   54  104    e 458
6   360   55  105    f 520
7   420   56  106    g 582
8   480   57  107    h 644
9   540   58  108    i 706
10  600   59  109    j 768

Итак, вопрос в том, как я могу преобразовать переменную / создать новую переменную и выбрать ее внутри одной mutate()?

Пример данных :

df <- data.frame(colA = 1:10,
colB = 50:59,
colC = 100:109,
colD = letters[1:10])

Ответы [ 3 ]

1 голос
/ 06 июня 2019

Переключение rowSums и select выполнит работу:

df %>% 
  mutate(colA = colA * 60,
          sum = colA + colB + colC)

Если у вас есть NA, сначала превратите их в ноль, чтобы они вели себя как и na.rm:

df %>% 
  replace(is.na(.), 0) %>%
  mutate(colA = colA * 60,
         sum = colA + colB + colC)

В качестве альтернативы вот решение, которое допускает rowSums и одно изменение:

df %>% 
  mutate(sum = rowSums(select(., colA:colC) * 
    matrix(rep(c(60,1,1), times = 10), byrow = T, ncol = 3), na.rm = T))

Вывод:

   colA colB colC colD sum
1     1   50  100    a 210
2     2   NA  101    b 221
3     3   52  102    c 334
4     4   53  103    d 396
5     5   54  104    e 458
6     6   55  105    f 520
7     7   56  106    g 582
8     8   57  107    h 644
9     9   58  108    i 706
10   10   59  109    j 768
1 голос
/ 06 июня 2019

. является заполнителем для того, что было отправлено в канал. В этом случае ваша мутация colA не обновляет то, что находится в конвейере при вызове mutate.

Вы можете добавить еще одну трубу:

df %>%
  mutate(colA = colA * 60)%>%
  mutate(sum = rowSums(select(., colA, colB, colC)))

1 голос
/ 06 июня 2019

Один из вариантов - добавить colA отдельно

library(dplyr)

df %>%
  mutate(colA = colA * 60,
         sum = rowSums(select(., colB, colC)) + colA)


#   colA colB colC colD sum
#1    60   50  100    a 210
#2   120   51  101    b 272
#3   180   52  102    c 334
#4   240   53  103    d 396
#5   300   54  104    e 458
#6   360   55  105    f 520
#7   420   56  106    g 582
#8   480   57  107    h 644
#9   540   58  108    i 706
#10  600   59  109    j 768

Когда вы используете select(., colA, colB, colC), . является исходным фреймом данных, а выбранные столбцы также взяты из исходного фрейма данных.Следовательно, он не имеет информации об обновленных значениях colA.По этой же причине вы получаете ошибку во второй попытке

rowSums(select(., colA_mod, colB, colC))

, поскольку столбец colA_mod не является частью исходного кадра данных (df).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...