Вокруг в зависимости от количества знаков после запятой - PullRequest
1 голос
/ 12 марта 2020

Что бы я хотел, чтобы

Я хотел бы округлить все числовые значения c большого набора данных в зависимости от их действительного десятичного знака.

Например, для df ниже я бы хотел округлить все числа, числа с одним десятичным знаком до целого числа и числа с двумя десятичными знаками до одного десятичного знака.

Обновление В исходном сообщении я использовал iris в качестве набора данных. Поскольку iris имеет только 1 десятичный знак, я добавил новый набор данных:

   df <- tibble(one=round(runif(100,0,10), 1),
                 two=round(runif(100,0,10), 2),
                 characters=rep("thanks",100))

Ответы [ 2 ]

4 голосов
/ 12 марта 2020

Вы можете просто посчитать цифры после точки и округлить до этого значения -1, т.е.

x <- c(4.5, 2.12, 3, 5.245)
i1 <- nchar(sub('.*\\.', '', x))

round(x, (i1-1))
#[1] 4.00 2.10 3.00 5.25
1 голос
/ 12 марта 2020

ДАННЫЕ:

 v1 <- c(1.1, 1.2, 2.91, 5.9)

РЕШЕНИЕ для вектора:

Ключом здесь является идентификация чисел с двумя десятичными знаками с помощью регулярного выражения с использованием grepl; чтобы заставить регулярное выражение работать, данные должны быть преобразованы в символ, используя as.character. Затем вы можете просто установить предложение ifelse, определяющее, что если условие оценивается как ИСТИНА, round до 1 десятичного знака, иначе округляется до 0 десятичных знаков:

ifelse(grepl(".\\d{2}$", as.character(v1)), round(v1,1), round(v1,0))

РЕЗУЛЬТАТ:

[1] 1.0 1.0 2.9 6.0

РЕШЕНИЕ для фрейма данных:

Тот же принцип можно применять для преобразования нескольких векторов в фрейме данных в один go:

dt <- data.frame(
  v1 = c(1.11, 2.2, 3.9, 5.55),
  v2 = c(6.99, 7.07, 8.5, 9.01))

Приведенное выше набросанное решение просто необходимо сделана частью функции внутри оператора apply:

apply(dt, 2, function(x) ifelse(grepl(".\\d{2}$", as.character(x)), round(x,1), round(x,0)))
      v1  v2
[1,] 1.1 7.0
[2,] 2.0 7.1
[3,] 4.0 8.0
[4,] 5.5 9.0
...