Mutating Column in 'Dplyr' Using 'Rowsums'

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 strshown 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



Leave a reply



Submit