I have a dataframe of the form:
4×4 DataFrame
Row │ ID Q1 Q2 Q3
│ Int64 Int64 Int64? Int64?
─────┼────────────────────────────────
1 │ 1 1 0 1
2 │ 2 1 1 0
3 │ 3 0 0 missing
4 │ 4 0 missing 1
The data are quiz answers, and missing
indicates that the person did not attempt the question.
I want to add two columns:

:score
for the number of correct responses; a* nd, 
:attempt
for the number of questions attempted.
Expected result
4×6 DataFrame
Row │ ID Q1 Q2 Q3 score attempts
│ Int64 Int64 Int64? Int64? Int64 Int64
─────┼────────────────────────────────────────────────
1 │ 1 1 0 1 2 3
2 │ 2 1 1 0 2 3
3 │ 3 0 0 missing 0 2
4 │ 4 0 missing 1 1 2
My best effort so far is:
julia> df1 = transform(df, r"Q" => (+) => :score)
4×5 DataFrame
Row │ ID Q1 Q2 Q3 score
│ Int64 Int64 Int64? Int64? Int64?
─────┼─────────────────────────────────────────
1 │ 1 1 0 1 2
2 │ 2 1 1 0 2
3 │ 3 0 0 missing missing
4 │ 4 0 missing 1 missing
which doesn’t give me totals for rows with missing values. I have tried various permutations of skipmissing
without success. Also I can’t quite work out an expression to count the nonmissing values in each row.
Thanks in advance.
EDIT:
@pdeffebach provides an efficient solution to the :score
problem. I also found a possibly less efficient solution which I can also apply to the :attempts
problem.
transform(df, r"Q" => ByRow((x...) > sum(skipmissing(x))) => :sum)
transform(df1, r"Q" => ByRow((x...) > count(>(1),skipmissing(x))) => :attempts)