How to draw a trunk and a sheet that shows a real sheet without rounding

For example, I have numbers: 43.2, 45.3, 48.1, 54.2 . When I use the stem () function to draw a graph, I get the following: the stem () function is displayed as follows

 x <- c(43.2, 45.3, 48.1, 54.2) stem(x) # # The decimal point is 1 digit(s) to the right of the | # # 4 | 3 # 4 | 58 # 5 | 4 

But from the plot, I can only know the numbers: 43,45,48,54 . So I want the function to draw a trunk and a sheet with which I can still know the exact number without rounding.

In addition, I want him to use only one number to represent the stem, showing the rest in the sheet. For example, 43.2 should be stem 4 , and sheet 3.2 , 43.22 should be stem 4 and sheet 3.22 . For numbers: 43.2, 45.3, 48.1, 54.2 . I need a plot like this:

enter image description here

+5
source share
2 answers
 x <- c(43.2, 45.3, 48.1, 54.2) stem(x) # # The decimal point is 1 digit(s) to the right of the | # # 4 | 3 # 4 | 58 # 5 | 4 stem2(x) # # The decimal point is 1 digit(s) to the right of the | # # 4 | 3.2 # 4 | 5.3, 8.1 # 5 | 4.2 stem2 <- function(x) { cx <- gsub('^.', ', ', as.character(sort(x))) co <- capture.output(stem(x)) m <- gregexpr('\\d(?!.*\\|)', co, perl = TRUE) l <- regmatches(co, m) l <- t(do.call('rbind', lapply(l, `length<-`, max(lengths(l))))) l[!is.na(l)] <- cx regmatches(co, m) <- data.frame(l) cat(gsub(' , ', ' ', co), sep = '\n') } 
+4
source

Here is one way. I used the data.table package below, so if you do not have it, install it first. If you really prefer the plot to be created using a regular data frame, let me know and I will adjust it accordingly.

 library(data.table) # Install via install.packages(data.table) # x is the vector of numbers for which you want to create the stem and leaf plot # leftDigits gives the position of the '|' relative to the decimal point, # eg leftDigits = 0 will result in 43.2 being represented as 43 | 0.2 # eg leftDigits = 1 will result in 43.2 being represented as 4 | 3.2 # I have included a rounding parameter, due to floating point problems seen when taking the difference of two numbers # rounding = 2 means that your numbers will show to 2 decimal places. Change as desired. myStem <- function(x, leftDigits, rounding = 2){ data = data.table("x" = x) # Create a data.table data[, left := floor(x/10^leftDigits)] # Get the number that will be to the left of '|' data[, right := round(x - left*10^leftDigits, rounding)] # The remainder will be on the right data = data[, paste(sort(right), collapse = ", "), by = left] # For each 'left', Place all the 'right' values in a comma separated string. data[, out := paste(left, " | ", V1), by = left] # Add the "|" cat(data$out, sep = "\n") # Output } # Example myStem(x = c(43.2, 45.3, 48.1, 54.2), 1) # 4 | 3.2, 5.3, 8.1 # 5 | 4.2 

Change If you need a reverse graph, then the following code should work. It works similarly to the previous code.

 myStem <- function(leftVals, rightVals, mainDigits, rounding = 10){ data = data.table("x" = leftVals, "ind" = "x") data = rbind(data, data.table("x" = rightVals, "ind" = "y")) data[, main := floor(x/10^mainDigits)] data[, right := round(x - main*10^mainDigits, rounding)] data = data[, ifelse(ind == "x", paste0(-sort(-right), collapse = ", "), paste0(sort(right), collapse = ", ")), by = c("ind", "main")] # For each 'main', Place all the 'right' values in a comma separated string. data = dcast(data, main ~ ind, value.var = "V1") data[, "left|" := ifelse(is.na(x), "", "|")] data[, "right|" := ifelse(is.na(y), "", "|")] data[, x := ifelse(is.na(x), "", x)] data[, y := ifelse(is.na(y), "", y)] data = data[, c("x", "left|", "main", "right|", "y"), with = F] maxLengthY = max(nchar(data$y)) data[, y := unlist(lapply(y, function(z) paste0(z, paste0(replicate(maxLengthY - nchar(z), " "), collapse = ""))))] colnames(data) = rep(" ", ncol(data)) data } # Example myStem(leftVals = c(43.2, 45.3, 48.1, 54.2), rightVals = c(30.2, 34.5, 44.3), 1) 1: 3 | 0.2, 4.5 2: 8.1, 5.3, 3.2 | 4 | 4.3 3: 4.2 | 5 
+1
source

All Articles