Mutating column in `dplyr` using `rowSums`
The examples do not work because you are nesting select
in mutate
and using bare variable names. In this case, select
is trying to do something like
> -df$ids
Error in -df$ids : invalid argument to unary operator
which fails because you can't negate a character string (i.e. -"i1"
or -"i2"
makes no sense). Either of the formulations below works:
df %>% mutate(blubb = rowSums(select_(., "X1", "X2")))
df %>% mutate(blubb = rowSums(select(., -3)))
or
df %>% mutate(blubb = rowSums(select_(., "-ids")))
as suggested by @Haboryme.
R mutate() with rowSums()
The difference in result might be due to the fact that part_langs
is a grouped dataframe, as can be seen from the output of str
shown in your post:
grouped_df [7 x 15] (S3: grouped_df/tbl_df/tbl/data.frame).
If this is the reason, then ungroup
first and rerun your code:
library(dplyr)
part_langs <- part_langs %>% ungroup
dplyr mutate rowSums calculations or custom functions
You can use rowwise()
function:
iris %>%
rowwise() %>%
mutate(sumVar = sum(c_across(Sepal.Length:Petal.Width)))
#> # A tibble: 150 x 6
#> # Rowwise:
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species sumVar
#> <dbl> <dbl> <dbl> <dbl> <fct> <dbl>
#> 1 5.1 3.5 1.4 0.2 setosa 10.2
#> 2 4.9 3 1.4 0.2 setosa 9.5
#> 3 4.7 3.2 1.3 0.2 setosa 9.4
#> 4 4.6 3.1 1.5 0.2 setosa 9.4
#> 5 5 3.6 1.4 0.2 setosa 10.2
#> 6 5.4 3.9 1.7 0.4 setosa 11.4
#> 7 4.6 3.4 1.4 0.3 setosa 9.7
#> 8 5 3.4 1.5 0.2 setosa 10.1
#> 9 4.4 2.9 1.4 0.2 setosa 8.9
#> 10 4.9 3.1 1.5 0.1 setosa 9.6
#> # ... with 140 more rows
"c_across()
uses tidy selection syntax so you can to succinctly select many variables"'
Finally, if you want, you can use %>% ungroup
at the end to exit from rowwise.
Why does my R mutate across with rowSums not work (Error: Problem with `mutate()` input `..2`. x 'x' must be numeric ℹ Input `..2` is `rowSums(.)`.)?
We may use adorn_totals
library(dplyr)
library(janitor)
test %>%
adorn_totals("col", name = "total")
-output
resource_name project sep_2021 oct_2021 total
Justin P1 1 5 6
Corey P2 2 2 4
Justin P3 NA 1 1
With rowSums
and across
, the syntax would be
test %>%
mutate(total = rowSums(across(contains("_20")), na.rm = TRUE))
-output
# A tibble: 3 x 5
resource_name project sep_2021 oct_2021 total
<chr> <chr> <dbl> <dbl> <dbl>
1 Justin P1 1 5 6
2 Corey P2 2 2 4
3 Justin P3 NA 1 1
In the OP's code, the across
selects the columns, but the rowSums
is done on the entire data (.
) instead of the one that is selected
Using mutate, if_else, and rowSums to create a new var based on condition
You can sum
the Data
value only where Code = 100
for each month
.
library(dplyr)
df %>%
group_by(month) %>%
mutate(newvar = sum(Data[Code == 100], na.rm = TRUE)) %>%
ungroup
Conditional mutating with regex in dplyr using rowSum
You could do:
test %>%
mutate(net_correct = select(.,setdiff(contains("total_score"), contains("partner"))) %>% replace(., . == -1, 0) %>% rowSums())
# total_score_1 total_score_2 partner_total_score_1 total_score_3 total_score_4 letter net_correct
#1 1 -1 1 1 -1 B 2
#2 1 1 1 -1 1 C 3
#3 -1 -1 -1 -1 1 A 1
R Dplyr mutate new column by calculating from other columns with conditionally replaced values
In base R
, we can subtract 1 from the data, use pmin
to restrict the value greater than 3 to 3 and get the rowSums
df$x3 <- rowSums(pmin(as.matrix(df-1), 3))
-output
> df
x1 x2 x3
1 1 5 3
2 2 4 4
3 3 3 4
4 4 2 4
5 5 1 3
mutate and rowSums exclude columns
I'm only just learning dplyr, so perhaps it is because of version upgrades, but this does now work:
d %>% mutate(Total=rowSums(select(d,-Epsilon, -Alpha)))
These days, I usually see folks use the dot notation:
d %>% mutate(Total=rowSums(select(.,-Epsilon, -Alpha)))
A slightly more manageable example:
df2 = data.frame(A=sample(0:20,10), B=sample(0:20, 10), C=sample(0:20,10), D=LETTERS[1:10])
df2
A B C D
1 19 0 9 A
2 6 10 14 B
3 13 20 6 C
4 20 4 15 D
5 9 14 8 E
6 11 1 18 F
7 4 15 13 G
8 17 5 0 H
9 16 3 16 I
10 2 6 1 J
df2 %>% mutate(total=rowSums(select(.,-D)))
A B C D total
1 19 0 9 A 28
2 6 10 14 B 30
3 13 20 6 C 39
4 20 4 15 D 39
5 9 14 8 E 31
6 11 1 18 F 30
7 4 15 13 G 32
8 17 5 0 H 22
9 16 3 16 I 35
10 2 6 1 J 9
NOTE:
The question you linked to has an updated answer that shows yet another new method that demonstrates some new dplyr features:
df2 %>% mutate(total=rowSums(select_if(., is.numeric)))
A B C D total
1 19 0 9 A 28
2 6 10 14 B 30
3 13 20 6 C 39
4 20 4 15 D 39
5 9 14 8 E 31
6 11 1 18 F 30
7 4 15 13 G 32
8 17 5 0 H 22
9 16 3 16 I 35
10 2 6 1 J 9
Use dplyr's mutate with columns that may or may not exist
One possibility:
library(dplyr)
df %>%
mutate(total = rowSums(across(matches("^\\w$"))))
This sums up every row that is named with a single letter.
If you want to sum up every row, replace matches("^\\w$")
by everything()
.
Related Topics
How to Get a Warning on "Shiny App Will Not Work If the Same Output Is Used Twice"
In Ggplot2, How to Add Additional Legend
How to Remove Na from Facet_Wrap in Ggplot2
Geom_Col Is Assigning the Wrong Independent Variable
Use Fortran Subroutine in R? Undefined Symbol
R Creating a Sequence Table from Two Columns
Combining Pivoted Rows in R by Common Value
How to Find Index of Match Between Two Set of Data Frame
Display Y-Axis for Each Subplot When Faceting
Get All the Rows with Rownames Starting with Abc111
Subtracting Values Group-Wise by the Average of Each Group in R
Shiny Dynamic Filter Variable Selection and Display of Variable Values for Selection
Colorize Parts of the Title in a Plot
How to Make PDF Download in Shiny App Response to User Inputs