Как рассчитать проценты из таблицы на R - PullRequest
0 голосов
/ 05 февраля 2019

Здравствуйте,

У меня есть таблица с 14 наблюдениями и 16 переменными.(От S0 до S11 и сумма строки в конце) Я хотел бы рассчитать процент каждого значения по итогу (последний столбец).Я попробовал prop.table, но это не дает мне правильные проценты.Я также пытался применить, но тот же пб.

Вот пример моей таблицы:

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 

The code I've tried : 

prop.table(df)

prop <- apply(df, 1, function(x) x/ df$Total*100)

Для первой строки, например, я хотел бы иметь (25987/41512) * 100 (269/41512) * 100 (269/ 41512) * 100 и т. Д.

Спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

prop.table() дает долю от общего количества по умолчанию, но имеет аргумент поля для расчета процентов строки или столбца.Я думаю prop.table(df[,2:7], margin = 1) * 100 должно работать.Где 1 указывает, что пропорции строки должны быть вычислены (2 указывает пропорции столбца).Индекс 2:7 исключает столбец Total и столбец Row.name, так как они не нужны для функции.

Редактирование: в зависимости от класса df может потребоваться преобразовать его вматрица первая.prop.table(as.matrix(df[,2:7]), margin = 1) * 100 должно работать в этом случае.

0 голосов
/ 05 февраля 2019

Вы можете использовать функции 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
0 голосов
/ 05 февраля 2019

Попробуйте:

prop <- apply(df, 2,function(x,y) (x/y)*100, df$Total)

Как вы можете прочитать из ?apply, второй аргумент:

вектор, дающий индексам, которыефункция будет применена болееНапример, для матрицы 1 обозначает строки, 2 обозначает столбцы

Поэтому вам следует использовать 2 вместо 1, если вы хотите вычислять процент по столбцам.Кроме того, ваша лямбда-функция требует дополнительного аргумента: это поле Total для каждой строки.Опять же, как вы можете прочитать из ?apply, все эти необязательные аргументы для функции должны идти в самом конце применения.

Наконец, просто поясните, что вы также создадите последний столбец, который всегда равен 1, потому чтов процентах от последнего столбца (Всего), он также должен быть рассчитан с помощью Применить.

Лучший!

...