Простой способ выровнять десятичное место - PullRequest
0 голосов
/ 02 июля 2018

Название само собой разумеющееся, знаете ли вы простой способ выровнять десятичную точку с R на этапе отчетности?

Например, если у меня есть вектор числовых значений:

с (2, 120, 12,5, 100,25, 0,1)

Я бы хотел, чтобы дисплей выглядел так:

  2
120
 12.5
100.25
  0.1

Я первый, кто удивился, что в R нет пакета для этого, так как я согласен, что это довольно распространенная проблема. Может быть, люди смогут решить эту проблему с помощью Markdown или другого трюка с отчетами?

Спасибо

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Это особый случай, но следующая функция должна делать то, что вы хотите. Я также включил аргумент «точность» для указания максимального числа десятичных знаков (должно быть больше 0).

alignedDigits <- function(df, originalvar, newvar, precision = 2) {
  originalvar <- enquo(originalvar) %>% quo_name()
  newvar <- enquo(newvar) %>% quo_name()

  df[[newvar]] <- round(df[[originalvar]], digits = precision)
  split.digits <- sprintf(paste0('%0.', as.character(precision), 'f'), df[[newvar]])

  split.digits <- strsplit(split.digits, '\\.') %>% 
    as.data.frame() %>% 
    as.matrix %>% 
    t

  split.digits[,2] <- sub('0+$', '', split.digits[,2])
  split.digits[,2] <- ifelse(split.digits[,2] == '', 0, split.digits[,2])

  maxima <- apply(split.digits, 2, function(x) max(nchar(x)))
  split.digits[,1] <- sapply(split.digits[,1], function(x) paste0(paste0(rep(' ', maxima[1] - nchar(x)), collapse = ''), x))
  split.digits[,2] <- sapply(split.digits[,2], function(x) paste0(x, paste0(rep(' ', maxima[2] - nchar(x)), collapse = '')))
  final.digits <- apply(split.digits, 1, function(x) paste(x[1], x[2], sep = '.'))
  df[[newvar]] <- final.digits
  return(df)
}

testok <- data.frame(y = c(12.1, 2, 0, 17, 1000.1, 57))
testnotok <- data.frame(y = c(2,120, 12.5, 100.25, .1))

alignedDigits(testok, y, m)

       y      m
1   12.1   12.1
2    2.0    2.0
3    0.0    0.0
4   17.0   17.0
5 1000.1 1000.1
6   57.0   57.0

alignedDigits(testnotok, y, z)

       y      z
1   2.00   2.0 
2 120.00 120.0 
3  12.50  12.5 
4 100.25 100.25
5   0.10   0.1 
0 голосов
/ 04 июля 2018

Хорошо, наконец, я решил написать функцию для этой цели. Он работает довольно хорошо, за исключением примера вектора, но я понятия не имею, почему, если кто-то может помочь, это было бы здорово.

AlignDec <- function(df, originalvar, newvar) {

  require(dplyr)

  originalvar <- enquo(originalvar) %>% quo_name()
  newvar <- enquo(newvar) %>% quo_name()

  decimalnumcount <- function(x) {

    out <- ifelse((x %% 1 != 0), nchar(strsplit(sub('.0+$', '', as.character(x)), ".", fixed = TRUE)[[1]][[2]]), 0)
    return(out)
  }

  IntNumCount <- function(x) {
    out <- nchar(as.character(trunc(x)))
    return(out)
  }

  df <- df %>% mutate(n_int = IntNumCount(.data[[originalvar]]), n_dec = decimalnumcount(.data[[originalvar]]), maxnint = max(n_int), maxndec = max(n_dec),
                      intpos = (maxnint - n_int), !!newvar := paste0(strrep(" ",intpos), prettyNum(.data[[originalvar]]))) %>% 
    select(-one_of(c("n_int", "n_dec", "maxnint", "maxndec", "intpos")))

  return(df)

}

Если я тестирую эти 2 кадра данных, это работает в первом случае, но не во втором, и я понятия не имею, почему!

testok <- data.frame(y = c(12.1, 2, 0, 17, 1000.1, 57))
testnotok <- data.frame(y = c(2,120, 12.5, 100.25, 0.1))

test1 <- AlignDec(testok, y, z)
test2 <- AlignDec(testnotok, y, z)

test2 возвращает мне это сообщение об ошибке:

Error in mutate_impl(.data, dots) : 
  Evaluation error: subscript out of bounds. 

Есть идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...