Вычислите смежные пропорции
У меня есть кадр данных:
x <- data.frame(id = letters[1:3], val0 = 1:3, val1 = 4:6, val2 = 7:9)
# id val0 val1 val2
# 1 a 1 4 7
# 2 b 2 5 8
# 3 c 3 6 9
В каждой строке я хочу рассчитать соответствующие пропорции (отношение) для каждого значения. Например. для значения в столбце "val0", я хочу рассчитать весовые значения val0/(val0 + val1 + val2).
Требуемый вывод:
id val0 val1 val2
1 a 0.083 0.33 0.583
2 b 0.133 0.33 0.533
3 c 0.167 0.33 0.5
Может ли кто-нибудь сказать мне, что это лучший способ сделать это? Здесь это всего три столбца, но может быть много столбцов.
Ответы
Ответ 1
И еще одна альтернатива (хотя это в основном красивая версия sweep
)... prop.table
:
> cbind(x[1], prop.table(as.matrix(x[-1]), margin = 1))
id val0 val1 val2
1 a 0.08333333 0.3333333 0.5833333
2 b 0.13333333 0.3333333 0.5333333
3 c 0.16666667 0.3333333 0.5000000
В разделе "описание" файла справки в ?prop.table
:
Это действительно sweep(x, margin, margin.table(x, margin), "/")
для новичков, за исключением того, что если margin имеет длину ноль, тогда получается x/sum (x).
Итак, вы можете видеть, что внизу, это действительно очень похоже на решение @Jilber.
И... это приятно для разработчиков R, чтобы быть внимательными к нам новичками, не так ли?:)
Ответ 2
следует выполнить трюк
cbind(id = x[, 1], x[, -1]/rowSums(x[, -1]))
## id val0 val1 val2
## 1 a 0.08333333 0.3333333 0.5833333
## 2 b 0.13333333 0.3333333 0.5333333
## 3 c 0.16666667 0.3333333 0.5000000
Ответ 3
Другая альтернатива, использующая sweep
sweep(x[,-1], 1, rowSums(x[,-1]), FUN="/")
val0 val1 val2
1 0.08333333 0.3333333 0.5833333
2 0.13333333 0.3333333 0.5333333
3 0.16666667 0.3333333 0.5000000
Ответ 4
Функция ns_to_percents
из пакета janitor выполняет следующее:
library(janitor)
ns_to_percents(x)
id val0 val1 val2
1 a 0.08333333 0.3333333 0.5833333
2 b 0.13333333 0.3333333 0.5333333
3 c 0.16666667 0.3333333 0.5000000
Это эквивалентно ns_to_percents(x, denom = "row")
, хотя "row"
является аргументом по умолчанию, поэтому в этом примере не требуется.
Если вы показываете результат, вы можете предпочесть janitor::adorn_crosstab
.
Отказ от ответственности: я создал пакет janitor, но считаю целесообразным опубликовать его; функция была создана для выполнения именно этой задачи, делая код более понятным для чтения, и пакет можно установить из CRAN.