R中茎叶图的分组
Grouping of Stem- Leaf plot in R
我有一个茎叶图作为问题,看起来像这样:
0 | 6
1 | 179
2 | 26
3 | 2478
4 | 15699
5 | 368
6 | 24457
7 |
8 | 56
所以,我自己创建了一个矢量,它会创建一个与上面相同的干图。
data <- c(06,11,17,19,22,26,32,34,37,38,41,45,46,49,49,53,56,58,62,64,64,65,67,7,85,86)
我要做的是,我需要将茎按 2 分组,然后使用 R 绘制相应的茎图。
解决方案看起来有点像这样:
0-2|6*179*26
3-5|2478*15699*368
6-8|244457**56
“*”用于分隔组中每个茎的叶子。即对于组stem 0-2,表示第一行的叶子6对应stem 0;叶子 1,7 和 9 对应于茎 1,叶子 2 和 6 对应于茎 2.
我发现 stem() 没有用,所以想用 "interval" 函数将数据除以 2,然后构建一个用户定义的函数,但结果给了我相同的 stem 值。
是否有任何方法可以通过使用内置函数/用户定义来获得所需的解决方案?
非常感谢。
这不会赢得任何选美比赛,但您绝对可以结合使用 cut
和一些字符串处理来创建您自己的分组 stem
函数。
这是一个示例函数,已注释以便您可以对其进行扩展以满足您的实际需要:
grouped_stem <- function(invec, n = 3) {
# Sequence of lowest tens and highest tens in the input data, by 10
cuts <- seq((min(invec) %/% 10) * 10, round(max(invec), -(nchar(max(invec))-1)), 10)
# For pretty labels in `cut`
labs <- sub("(.*).$", "\1", cuts)
labs <- replace(labs, !nzchar(labs), "0")
# List of the values according to their `cut` intervals
temp <- split(invec, cut(invec, cuts, labs[-length(labs)], right = FALSE))
# Only interested in the last digit
temp <- relist(sub(".*(.)$", "\1", unlist(temp, use.names = FALSE)), temp)
# Paste the values together. Add in a "*" that we can get rid of later if not required
combined <- vapply(temp, function(y) sprintf("%s*", paste(y, collapse = "")), character(1L))
# Split by number of groups of tens per stem
splits <- split(combined, ((seq_along(combined)-1) %/% n))
# Construct the stems and leaves
stems <- vapply(splits, function(x) {
paste(names(x)[1], names(x)[length(x)], sep = " to ")
}, character(1L))
leaves <- vapply(splits, function(x) {
sub("[*]$", "", paste(x, sep = "", collapse = ""))
}, character(1L))
# Print and store
cat(sprintf(sprintf("%%%ss | %%s", max(nchar(stems))+2), stems, leaves), sep = "\n")
invisible(setNames(as.list(leaves), stems))
}
运行 在您的样本数据上,它产生:
grouped_stem(data)
## 0 to 2 | 67*179*26
## 3 to 5 | 2478*15699*368
## 6 to 8 | 24457**56
我有一个茎叶图作为问题,看起来像这样:
0 | 6
1 | 179
2 | 26
3 | 2478
4 | 15699
5 | 368
6 | 24457
7 |
8 | 56
所以,我自己创建了一个矢量,它会创建一个与上面相同的干图。
data <- c(06,11,17,19,22,26,32,34,37,38,41,45,46,49,49,53,56,58,62,64,64,65,67,7,85,86)
我要做的是,我需要将茎按 2 分组,然后使用 R 绘制相应的茎图。
解决方案看起来有点像这样:
0-2|6*179*26
3-5|2478*15699*368
6-8|244457**56
“*”用于分隔组中每个茎的叶子。即对于组stem 0-2,表示第一行的叶子6对应stem 0;叶子 1,7 和 9 对应于茎 1,叶子 2 和 6 对应于茎 2.
我发现 stem() 没有用,所以想用 "interval" 函数将数据除以 2,然后构建一个用户定义的函数,但结果给了我相同的 stem 值。
是否有任何方法可以通过使用内置函数/用户定义来获得所需的解决方案? 非常感谢。
这不会赢得任何选美比赛,但您绝对可以结合使用 cut
和一些字符串处理来创建您自己的分组 stem
函数。
这是一个示例函数,已注释以便您可以对其进行扩展以满足您的实际需要:
grouped_stem <- function(invec, n = 3) {
# Sequence of lowest tens and highest tens in the input data, by 10
cuts <- seq((min(invec) %/% 10) * 10, round(max(invec), -(nchar(max(invec))-1)), 10)
# For pretty labels in `cut`
labs <- sub("(.*).$", "\1", cuts)
labs <- replace(labs, !nzchar(labs), "0")
# List of the values according to their `cut` intervals
temp <- split(invec, cut(invec, cuts, labs[-length(labs)], right = FALSE))
# Only interested in the last digit
temp <- relist(sub(".*(.)$", "\1", unlist(temp, use.names = FALSE)), temp)
# Paste the values together. Add in a "*" that we can get rid of later if not required
combined <- vapply(temp, function(y) sprintf("%s*", paste(y, collapse = "")), character(1L))
# Split by number of groups of tens per stem
splits <- split(combined, ((seq_along(combined)-1) %/% n))
# Construct the stems and leaves
stems <- vapply(splits, function(x) {
paste(names(x)[1], names(x)[length(x)], sep = " to ")
}, character(1L))
leaves <- vapply(splits, function(x) {
sub("[*]$", "", paste(x, sep = "", collapse = ""))
}, character(1L))
# Print and store
cat(sprintf(sprintf("%%%ss | %%s", max(nchar(stems))+2), stems, leaves), sep = "\n")
invisible(setNames(as.list(leaves), stems))
}
运行 在您的样本数据上,它产生:
grouped_stem(data)
## 0 to 2 | 67*179*26
## 3 to 5 | 2478*15699*368
## 6 to 8 | 24457**56