【问题标题】:shiny sorting numbers as strings闪亮的将数字排序为字符串
【发布时间】:2016-02-14 03:41:04
【问题描述】:

我正在使用 DT 包中的 shiny 和 renderDataTable 函数在我的 web 应用程序中显示一个表。排序时,似乎将数字视为字符串,按第一个数字排序,然后按第二个数字排序,依此类推,即应该排序为 1、2、5、100、250 的内容将排序为 1、100、2、250、5

我尝试在读取 csv 时指定 colClasses,但似乎不起作用。

server.R 显示,我的 ui.R 只是一个 dataTableOutput

library(DT)
library(dplyr)
date <- format(Sys.Date() - 1, '%Y_%m_%d')
date2 <- format(Sys.Date() - 2, '%Y_%m_%d')

# Read data in
tab1 <- read.csv(paste0(date, '_tabs.csv'), stringsAsFactors = FALSE, colClasses = c('character', rep('integer', 9)))
tab1 <- na.omit(tab1)
tab2 <- read.csv(paste0(date2, '_tabs.csv'), stringsAsFactors = FALSE, colClasses = c('character', rep('numeric', 9)))

# Ensuring both tables have matching values for country
tab3 <- tab2[tab2$X %in% tab1$X, ]
missingr <- setdiff(tab1$X, tab3$X)
for (j in missingr) {
  tab3 <- rbind(tab3, rep(0, length(tab1)))
  tab3[nrow(tab3), 1] <- j
}

# Sorting by country and creating a new dataframe of differences
Country <- tab1$X
tab1 <- arrange(tab1, X)
tab3 <- arrange(tab3, X)
tab1 <- tab1[, !(names(tab1) %in% 'X')]
tab3 <- tab3[, !(names(tab3) %in% 'X')]
tab2 <- tab1 - tab3

# Adding total column and country column to dataframes
c1 <- c('Total', colSums(tab1))
c2 <- c('Total', colSums(tab2))
rownames(tab2) <- Country
tab2 <- data.frame(Country, tab2)
tab1 <- data.frame(Country, tab1)
tab1 <- tab1[tab1$total > 100, ]
tab2 <- tab2[tab2$Country %in% tab1$Country, ]
tab1 <- rbind(tab1, c1)
tab2 <- rbind(tab2, c2)


shinyServer(function(input, output) {
  output$tab1 <- renderDataTable({tab1},
    rownames = FALSE, options = list(lengthMenu = list(c(20, 10, -1), c('20', '10', 'All')), 
    initComplete = JS("function(settings, json) {","$(this.api().table().header()).css({'background-color': '#000', 'color': '#fff'});","}"),
      autoWidth = TRUE,
      columnDefs = list(list(width = '200px', targets = "_all"))
    ))
  output$tab2 <- renderDataTable({tab2},
    rownames = FALSE, options = list(lengthMenu = list(c(20, 10, -1), c('20', '10', 'All')), 
    initComplete = JS("function(settings, json) {","$(this.api().table().header()).css({'background-color': '#000', 'color': '#fff'});","}"),
      autowidth = TRUE,
      columnDefs = list(list(width = '200px', targets = "_all"))
    ))
}
)

【问题讨论】:

  • 您在哪里订购桌子? renderDataTable 默认情况下不对表进行排序。 rstudio.github.io/DT/options.html 的第 4.1 节解释了 order-option
  • 点击一列对其进行排序,就像在您刚刚链接的页面上一样,按最左边的列排序的默认选项是我最初想要的(按国家排序),然后用户可以单击一列对它们进行排序。
  • 尝试在您创建的表上使用str。它会告诉你你有什么样的数据并且将输出添加到你的问题中会很有帮助。
  • 我没有足够的代表来发布图片,但这是链接,直到有人将其删除i.imgur.com/No7SiJT.png pic 显示了当您单击最左侧的数字列进行排序时会发生什么。读取 csv 文件时的 X 列是国家/地区代码,因此无论如何都需要是字符。其余列应为 nums/ints

标签: r sorting shiny


【解决方案1】:

在我们的 Rshiny 应用程序上对列进行排序时,我们也遇到了同样的问题。我们发现它是由 cbind 将我们的数值转换为字符串引起的。

> foo=c(111,10,3,4,5)
> bar=c("should","it","order","like","yoda")

> df1 = data.frame(cbind(foo,bar))
> df1[order(df1[,1]),]

  foo    bar
2  10     it
1 111 should
3   3  order
4   4   like
5   5   yoda

您可以通过检查来验证这一点

> str(df1)
'data.frame':   5 obs. of  2 variables:
 $ foo: Factor w/ 5 levels "10","111","3",..: 2 1 3 4 5
 $ bar: Factor w/ 5 levels "it","like","order",..: 4 1 3 2 5

这是因为首先调用 cbind,然后创建一个字符数组。当您考虑它时,这是很自然的,因为数组需要具有相同类型的所有元素,并且数字可以转换为字符,但不能反过来。 这可以通过在数据框对象上使用 cbind 来轻松避免:

> df2 = cbind(data.frame(foo),data.frame(bar))
> df2[order(df2[,1]),]

  foo    bar
3   3  order
4   4   like
5   5   yoda
2  10     it
1 111 should

或者在这个例子中,直接从字符串和数字数组创建一个新的数据框可能更优雅:

> df3 = data.frame(foo,bar)
> df3[order(df3[,1]),]

  foo    bar
3   3  order
4   4   like
5   5   yoda
2  10     it
1 111 should

【讨论】:

    【解决方案2】:

    在创建c1时,我没有意识到它是一个字符向量,当将它绑定到最后的数据帧时,整个数据帧最终变成了字符。

    感谢@user5029763

    【讨论】:

      【解决方案3】:

      # Sorting by country and creating a new dataframe of differences 下我会包含一个as.numeric(tab1$X)。通常,您可以使用该函数将数值类型值强制转换为实际数值。

      【讨论】:

      • 直接从因子到数字是丢失信息的好方法,例如year &lt;- factor(1999:2004); as.numeric(year)。您应该始终使用as.numeric(as.character(...))
      • 确实如此。 OP 说它们似乎是“字符串”,并且它们按数字排序的事实表明它们是字符向量而不是因子。但你是对的。为了安全起见,使用 as.numeric(as.character(...)) 很聪明
      • 因子默认按字符串排序,因此按数字排序表示因子与表示字符一样多。鉴于 R 中的 stringsAsFactors=TRUE 默认值 - 并且这是一个数据框 - 使得因素 much 的可能性更大。您必须非常清楚要在数据框中获取字符向量而不是因子。
      • 我并不是要不愉快 - 我只是认为这是一个非常冒险的建议。如果您编辑您的问题以建议as.numeric(as.character(tab1$X)),或者至少建议查看str(tab1)sapply(tab1, class) 以首先确定课程,我很乐意将我的反对票改为赞成票。
      猜你喜欢
      • 1970-01-01
      • 2012-01-20
      • 2021-11-22
      • 2010-11-18
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      相关资源
      最近更新 更多