Reputation: 183
My goal is to count the total number of tasks each person (variable = name) has done. One person can do only one task per day.
My dataset looks like this:
name task1 task2 task3 day
bill TRUE FALSE FALSE 1
bill FALSE TRUE FALSE 2
bill FALSE FALSE FALSE 3
bill NA NA NA 4
alex FALSE FALSE FALSE 1
alex TRUE FALSE FALSE 2
alex FALSE FALSE FALSE 3
alex NA NA NA 4
rob TRUE FALSE FALSE 1
rob TRUE FALSE FALSE 2
rob TRUE FALSE FALSE 3
rob NA NA NA 4
This is the output that I need:
name total
bill 2
alex 1
rob 3
My code: (As you can see I can summarise the number of tasks, but the output is still far away from what I need)
total <- sum1%>%
group_by(`name`)%>%
summarise(task1_processed=sum(task11, na.rm = TRUE), task2_processed = sum(task2, na.rm = TRUE),
task3_processed = sum(task3, na.rm = TRUE))
Upvotes: 3
Views: 1235
Reputation: 101608
A data.table
option
setDT(df)[, .(total = sum(na.omit(unlist(.SD)))), name, .SDcols = patterns("^task")]
gives
name total
1: bill 2
2: alex 1
3: rob 3
Upvotes: 0
Reputation: 41220
You could use c_across
to sum
logical values across all columns:
library(dplyr)
df %>% group_by(name) %>%
summarize(total = sum(c_across(where(is.logical)), na.rm = TRUE)) %>%
ungroup
name total
<chr> <int>
1 alex 1
2 bill 2
3 rob 3
Upvotes: 0
Reputation: 388982
For each name
you can sum
the 'task'
columns together.
library(dplyr)
df %>%
group_by(name) %>%
summarise(total = sum(unlist(select(cur_data(), starts_with('task'))), na.rm = TRUE))
# name total
#* <chr> <int>
#1 alex 1
#2 bill 2
#3 rob 3
Upvotes: 2
Reputation: 39858
One option could be:
df %>%
group_by(name) %>%
summarise(n = sum(unlist(across(starts_with("task"))), na.rm = TRUE))
name n
* <chr> <int>
1 alex 1
2 bill 2
3 rob 3
Or:
df %>%
group_by(name) %>%
summarise(n = sum(Reduce(`+`, across(starts_with("task"))), na.rm = TRUE))
Upvotes: 1