我使用闪亮的DT包中的renderDataTable函数在我的webapp中显示一个表。在排序时,它似乎将数字视为字符串,按第一个数字排序然后排序第二个等等,即排序为1,2,5,100,250的排序分别为1,100,2,250,5 < / p>
我在阅读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"))
))
}
)
答案 0 :(得分: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,然后创建一个char数组。考虑一下它是很自然的,因为数组需要具有相同类型的所有元素,并且数字可以转换为char,但不能相反。 通过在数据框对象上使用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
答案 1 :(得分:0)
创建c1时,我没有意识到它是一个字符向量,当它将结尾处的数据帧结束时,整个数据帧最终成为字符。
感谢@ user5029763
答案 2 :(得分:-1)
在# Sorting by country and creating a new dataframe of differences
下,我会添加as.numeric(tab1$X)
。通常,您可以使用该函数将数值类型值强制转换为实际数值。