考虑这样的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)))
切换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