r语言 - select() 一个 mutate() 中的转换/新变量



考虑这样的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",然后计算我通过在 mutate() 内部select()选择的变量的行和。我正在这样做:

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])

现在可以通过 dplyr> 1.0.0 中的cur_data()实现

此功能
library(dplyr)
df %>%
  mutate(colA = colA * 60,
         sum = rowSums(select(cur_data(), 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
<小时 />

较早的答案

一种选择是单独添加colA

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 ( 的一部分。

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

您可以添加另一个管道:

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

切换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

最新更新