Вы можете использовать функции tidyverse набор , мутирование , выбор и распространение .
Загрузка пакетов и данных:
library(dplyr)
library(tidyr)
sampletable <- "Row.name S0 S1 S2 S3 S4 S5 Total
S0 25987 269 9152 6042 30 32 41512
S1 234 5575 768 4398 3321 34 14330
S2 345546 35 79 245 21685 676 368266
S3 5678 6 78 987 4657 789 12195
S4 9 45 879 34 5768 246 6981
S5 54 3 788 863 56 279826 281590
S6 367 57678 12 842 436 5824 65159 "
dtf <- read.table(text= sampletable, header = TRUE)
# I prefer lowercase names
names(dtf) <- tolower(names(dtf))
Преобразование данных в длинном формате, одно наблюдение на строку
dtflong <- dtf %>%
gather(col.name, value, -row.name, -total) %>%
mutate(percent = round(value / total *100, 2))
head(dtflong)
row.name total col.name value percent
1 S0 41512 s0 25987 62.60
2 S1 14330 s0 234 1.63
3 S2 368266 s0 345546 93.83
4 S3 12195 s0 5678 46.56
5 S4 6981 s0 9 0.13
6 S5 281590 s0 54 0.02
Изменение формы в широком формате
dtflong %>%
select(-total, -value) %>%
spread(col.name, percent)
row.name s0 s1 s2 s3 s4 s5
1 S0 62.60 0.65 22.05 14.55 0.07 0.08
2 S1 1.63 38.90 5.36 30.69 23.18 0.24
3 S2 93.83 0.01 0.02 0.07 5.89 0.18
4 S3 46.56 0.05 0.64 8.09 38.19 6.47
5 S4 0.13 0.64 12.59 0.49 82.62 3.52
6 S5 0.02 0.00 0.28 0.31 0.02 99.37
7 S6 0.56 88.52 0.02 1.29 0.67 8.94
При желании проверьте правильность итогового столбца
dtflong %>%
group_by(row.name, total) %>%
summarise(total2 = sum(value)) %>%
mutate(diff = total2 - total)
# A tibble: 7 x 4
# Groups: row.name [7]
row.name total total2 diff
<fct> <int> <int> <int>
1 S0 41512 41512 0
2 S1 14330 14330 0
3 S2 368266 368266 0
4 S3 12195 12195 0
5 S4 6981 6981 0
6 S5 281590 281590 0
7 S6 65159 65159 0