Округлить в R с одним ограничением

#r #rounding

#r #округление

Вопрос:

У меня есть этот набор данных:

 B <- c(60.65, 25.25)
D <- c(10, 10)
E <- c(30.35, 65.75)
Total <- c(100,100) 
  

Я хочу округлить столбцы с учетом B D E = 100

Большое вам спасибо за вашу помощь.

Приветствую вас!

Комментарии:

1. Мне непонятно, что вы пытаетесь сделать. Можете ли вы объяснить, что именно вы хотите, чтобы здесь произошло?

2. Я думаю, что существует несколько решений, когда исходные элементы не суммируются до 100. Я предполагаю, что если сумма всегда завышена на 100, вы можете использовать trunc

Ответ №1:

Я предполагаю , что вы спрашиваете о том , как масштабировать записи из B , D , E таким образом , чтобы они суммировались Total . На мой взгляд, слово «круглый» здесь не имеет особого смысла.

Если это так, вы можете выполнить следующее

 df <- data.frame(B, D, E) * Total / rowSums(data.frame(B, D, E))
df
#        B       D        E 
#1 60.0495 9.90099 30.04950 
#2 25.0000 9.90099 65.09901
  

data.frame df Затем содержит масштабированные векторы столбцов B , D , E . Мы можем подтвердить, что действительно компоненты суммируются до Total

 rowSums(df)
#[1] 100 100
  

Комментарии:

1. Я думаю, что цель состоит в том, чтобы получить целые числа, поэтому после масштабирования до 100 столбцы B и D следует округлить, а E вычислить как 100 минус сумма B и D.

2. @GrzegorzSionkowski Это не очень понятно из сообщения OPs. Что касается вашей интерпретации: зачем вычислять E = 100 - (round(B) round(D)) , почему нет B = 100 - (round(E) round(D)) или D = 100 - (round(B) round(E)) ? Все это даст вам немного разные округленные значения для B , D , E . Вы понимаете, к чему я клоню?

3. Я говорю о вычитании, потому что может быть такой случай, когда простое округление после масштабирования может не дать сумму, равную 100.

4. @GrzegorzSionkowski Да, я понял вашу точку зрения; я показывал вам, что ваш метод «вычитания» неоднозначен и может давать разные округленные B D E значения , , в зависимости от того, как вы вычитаете.

5. Произвольно выбранный столбец является решением для случая, когда простое округление масштабированных B, D, E не дает суммы, равной 100. Очень редкий случай.

Ответ №2:

Суммы значений строк близки к 100, но простое округление не всегда дает 100, например, первая строка. Итак, перед округлением давайте выполним масштабирование, которое изменит сумму значений строк с «близких» на точно равную 100. Однако может возникнуть такая ситуация, что даже округление после масштабирования не дает суммы, равной 100, поэтому давайте исправим это, изменив значения одного из столбцов:

 # additional value 100/3
B <- c(60.65, 25.25, 100/3)
D <- c(10, 10, 100/3)
E <- c(30.35, 65.75, 100/3)
Total <- c(100, 100, 100) 

df <- round(data.frame(B, D, E)*100/rowSums(data.frame(B, D, E)))

df
#   B  D  E
#1 60 10 30
#2 25 10 65
#3 33 33 33

rowSums(df)
#[1] 100 100  99

df[,3] <- 100 - rowSums(df[,1:2])

df
#   B  D  E
#1 60 10 30
#2 25 10 65
#3 33 33 34

rowSums(df)
#[1] 100 100 100