Я дам ответ в формате тидыр.Ваши данные в "широком" формате.Это делает его очень читаемым человеком, но не обязательно машиночитаемым.Первый шаг к тому, чтобы сделать его более аккуратным, - преобразовать данные в длинный формат.Другими словами, давайте преобразуем данные, чтобы нам не приходилось выполнять вычисления по нескольким столбцам в одной строке.
аккуратный формат позволяет использовать группирование переменных, создавать сводки и т. Д.
library(dplyr)
library(tidyr)
df <- data.frame(C1 = c("F","M"),
C2 = c("F","M"),
C3 = c("M","F"),
C4 = c("M","M"),
stringsAsFactors = FALSE)
> df
C1 C2 C3 C4
1 F F M M
2 M M F M
Давайте добавим поле «id», чтобы мы могли отслеживатькаждого уникального ряда.Это то же самое, что и номер строки ... но мы собираемся конвертировать широкие данные в длинные данные с разными номерами строк.Затем используйте команду collect для преобразования из широких данных в длинные.
df_long <- df %>%
mutate(id = row_number(C1)) %>%
gather(key = "key", value = "value",C1:C4)
> df_long
id key value
1 1 C1 F
2 2 C1 M
3 1 C2 F
4 2 C2 M
5 1 C3 M
6 2 C3 F
7 1 C4 M
8 2 C4 M
Теперь можно использовать group_by()
для группировки на основе переменных, выполнения суммирования и т. Д.
Для того, что вы просили, сгруппируйте по столбцу id, а затем выполните вычисления для группы.В этом случае мы возьмем сумму всех значений, которые являются "F".Затем мы разгруппируемся и вернемся к широко читаемому формату.
df_long %>%
group_by(id) %>%
mutate(response = sum(value=="F",na.rm=TRUE)) %>%
ungroup()
> df_long
# A tibble: 8 x 4
id key value response
<int> <chr> <chr> <int>
1 1 C1 F 2
2 2 C1 M 1
3 1 C2 F 2
4 2 C2 M 1
5 1 C3 M 2
6 2 C3 F 1
7 1 C4 M 2
8 2 C4 M 1
Чтобы получить данные в широком формате, как только вы закончите, выполнив все необходимые вычисления в длинном формате:
df <- df_long %>%
spread(key,value)
> df
# A tibble: 2 x 6
id response C1 C2 C3 C4
<int> <int> <chr> <chr> <chr> <chr>
1 1 2 F F M M
2 2 1 M M F M
Чтобы вернуть данные в том порядке, в котором они у вас были:
df <- df %>%
select(-id) %>%
select(C1:C4,everything())
> df
# A tibble: 2 x 5
C1 C2 C3 C4 response
<chr> <chr> <chr> <chr> <int>
1 F F M M 2
2 M M F M 1
Конечно, вы можете использовать каналы, чтобы сделать все это водин шаг.
df <- df %>%
mutate(id = row_number(C1)) %>%
gather(key = "key", value = "value",C1:C4) %>%
group_by(id) %>%
mutate(response = sum(value=="F",na.rm=TRUE)) %>%
ungroup() %>%
spread(key,value) %>%
select(-id) %>%
select(C1:C4,everything())