在一个mutate()中进行select()转换/新变量

时间:2019-06-06 09:02:18

标签: r dplyr

考虑这样的df:

   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 个答案:

答案 0 :(得分:1)

一种选择是分别添加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)。

答案 1 :(得分:1)

切换rowSumsselect将完成任务:

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

答案 2 :(得分:1)

.是发送到管道中的内容的占位符。在这种情况下,您对colA的更改不会更新mutate调用中管道中的内容。

您可以添加另一个管道:

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