【问题标题】:How to keep the trailing zeros when converting a numeric object to character object in R?在R中将数字对象转换为字符对象时如何保留尾随零?
【发布时间】:2021-10-12 09:26:50
【问题描述】:

下面是我在处理 R 中将数字对象转换为字符对象时遇到的问题的屏幕截图。否则数据框是正确的,但在字符“46”和“104”之后缺少尾随零”。

考虑以下 MWE:

library(dplyr)

# I first created random data and then created quintiles from the data.
# The random data are listed below:
testdata1 <- structure(list(X = c(62.5229689071269, 145.825042620083, 124.871684774549, 
                                86.2501301893607, 101.433010648648, 144.618979893455, 110.778688415318, 
                                45.9851314727384, 106.411772801465, 56.7832887263229, 162.318035050403, 
                                72.8574239442922, 133.416450070424, 137.670510111283, 107.965525693767, 
                                114.545917853894, 103.963829924899, 123.393869519699, 70.6355172309528, 
                                67.4792934191092), quintiles = structure(c(1L, 5L, 4L, 2L, 2L, 
                                5L, 3L, 1L, 3L, 1L, 5L, 2L, 4L, 5L, 3L, 4L, 3L, 4L, 2L, 1L),
                                .Label = c("[46,70]", "(70,103]", "(103,112]", "(112,134]", "(134,162]"),
                                class = "factor")), row.names = c(NA, 20L), class = "data.frame")

# A new dataframe "testdata2" will show in 4 columns:
# 1) quintiles,
# 2) min. value of X in each quintile,
# 3) max. value of X in each quintile, and
# 4) the range between mins and maxs within the quintiles:

testdata2 <- as.data.frame(levels(testdata1$quintiles))
names(testdata2)[1] <- 'Quintiles'

testdata2$Min <- testdata1 %>% group_by(quintiles) %>% summarise(X = min(X)) %>%
  select(X)  %>% mutate(across(where(is.numeric), round, 1)) %>% as.matrix %>% as.character

testdata2$Max <- testdata1 %>% group_by(quintiles) %>% summarise(X = max(X)) %>%
  select(X)  %>% mutate(across(where(is.numeric), round, 1)) %>% as.matrix %>% as.character

testdata2$Range <- format(paste(testdata2$Min, testdata2$Max, sep="-"))

View(testdata2)

作为旁注,我很难避免将整个向量(所有最小值和所有最大值)投影到数据框中的每个单独的单元格。如果你从代码中删除两个 as.matrix 函数,你就会明白我的意思了。有没有比使用 as.matrix 更优雅的方式来实现结果?

非常感谢任何帮助。

【问题讨论】:

  • 你能创建一个不需要不必要的外部包的例子吗?我不明白你的问题,但是如果不先安装“gtools”包,我就无法执行你的示例(如果我理解正确,它实际上与你的问题无关)。 (即便如此,我认为您的示例实际上并未演示“尾随零”,这可能是因为您使用的是随机数而没有固定种子)。请使用dput 发布示例数据集。
  • 我很抱歉,你是完全正确的。根据您的建议,我现在已经使用 dput 重写了代码。我希望它现在更有意义。

标签: r dataframe character decimal rounding


【解决方案1】:

您可以使用sprintf 而不是将字符串粘贴在一起,而是对格式进行大量控制。

> sprintf("%d.0-%d.0", 71, 100)
[1] "71.0-100.0"

编辑

完整的作品看起来与此类似。

testdata1 %>% 
  group_by(quintiles) %>% 
  mutate(
    Min = min(X),
    Max = max(X),
    Range = sprintf("%.1f-%.1f", Min, Max)
    ) 

sprintf 将整理格式和前导 0。 感谢罗兰的指正,不知道我在上面做什么

【讨论】:

  • 是的,sprintf 可以在这里使用。但是,您的格式字符串是错误的。它应该类似于sprintf("%.1f-%.1f", 71.1, 100)
  • @Quixotic22,你能说得更具体点吗?我以这样一种方式重写了代码,以便评论者现在可以使用我的原始随机数据。 (在发布问题之前,我已经尝试了 sprintf,但无济于事。)
  • 补充说明
  • 我确认您的代码不仅完美地解决了 1) 尾随零/小数消失的问题,而且 2) 我的问题中提到的“作为旁注”问题。此外,代码变得更加整洁(无意中的双关语)。感谢你们,甚至是建议使用 dput 的用户。
  • @jaggedjava,最好的方法是将上面的mutate动词实际更改为summarise
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 2018-12-08
  • 2014-04-18
  • 2014-02-09
  • 1970-01-01
相关资源
最近更新 更多