更改数据表中的列宽(在一列或不在一列中包含 URL)
Change column width in datatable (with URLs in one column or without)
这是我的第一个问题,所以如果我做错了什么请告诉我。
几天来,我一直在尝试在 Shiny App 中格式化 table,我尝试了所有方法,但我完全卡住了。
我有一个 table,理想情况下应该包括 14 列,其中大部分可能非常窄。但是,有 2 列包含长字符串,一列包含普通文本,另一列包含 URLs(文本列中信息的来源)。我希望第一个很宽,以便文本易于阅读,并且我不太关心 URL 列。我在某处读到 datatable 会自动尝试使列适合最长的单词,我发现这可能是这里的问题,因为无论我如何尝试设置列宽,URL 列都会结束向上很宽,其他的(包括文本列)很窄。但我想我可能有 2 个不同的问题:
问题 1:
我试图生成一个最小的可重现示例,但我发现确实是 URL 列搞乱了所有内容。
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by="days"), each=5 )
var2 <- rep(c("a", "b", "c", "d", "e"), each=10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA,8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
selection <- datatable(
df[var3!="NA", c("var1", "var2", "var3", "var4", "var6")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1,2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='80%')), (list(targets=c(4,5), visible=TRUE, width='5%')))))
截图:https://i.ibb.co/qkxw6Hm/Screenshot-from-2022-02-07-12-20-57.png
...而如果我不包含 URL 列:
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by="days"), each=5 )
var2 <- rep(c("a", "b", "c", "d", "e"), each=10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA,8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
selection <- datatable(
df[var3!="NA", c("var1", "var2", "var3", "var6")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1,2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='85%')), (list(targets=c(4), visible=TRUE, width='5%')))))
截图:https://i.ibb.co/rsgvD2b/Screenshot-from-2022-02-07-12-24-35.png
你对如何处理这个问题有什么建议吗?有没有一种方法可以在数据table 中格式化URLs,这样您就只会将短文本显示为可点击的link?还是有什么办法可以强制DT在“字”长的情况下挤列?
问题 2:
实际上,我已经放弃并决定删除带有 URL 的专栏并告诉 reader 如果他们想查看源代码,他们应该下载 .csv 文件。但是在我真正的 Shiny App 中设置列宽无论如何都不起作用。这是我实际 table 的代码,没有 URL 列:
output$selection <- renderDT(DT::datatable(
df[country==input$selection&change!="NA", c("date", "country", "change", "strictest_night", "strictest_day", "least_strict_night", "least_strict_day", "stayhome_day", "stayhome_night", "walk_day", "walk_night", "leave_municip", "outside_masks", "difference_with_oxcgrt")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1, 2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='35%')), (list(targets=c(4:14), visible=TRUE, width='5%'))))))
下面是我在 UI 中调用 table 的方式:
selectInput("selection","select country/territory", choices=unique(df$country)),
tags$style(HTML("
.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate {
color: #ffffff;
}
thead {
color: #ffffff;
}
"
)),
DTOutput("selection")
它在主面板中,上面有一个标签集面板,但我认为这无关紧要。我认为错误可能出在 HTML 样式代码中,因为坦率地说,我只是从某个地方复制了它。但是我把它注释掉了,我仍然有同样的问题。那可能是什么问题呢?我的列太多了吗?
下面是 table 的样子:https://i.ibb.co/XZ6hNH5/Screenshot-from-2022-02-07-13-07-43.png
非常感谢!
已找到解决方案:
danlooo 已经回答了问题1。再次感谢!对于问题 2,我在这里找到了解决方案:Setting column width in R Shiny DataTable does not work in case of lots of column DT输出本身。我认为指定主面板宽度就足够了,但事实并非如此。我保留了所有内容,只是在 UI 中调用 table 时添加了一个宽度参数: DTOutput("selection", width="2000px") ... 它有效!
如果您使用 datatable(escape = FALSE)
:
,您可以创建 HTML link 而不是仅将 URL 显示为原始文本
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by = "days"), each = 5)
var2 <- rep(c("a", "b", "c", "d", "e"), each = 10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA, 8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
# Transform text to HTML
df$var4 <- sapply(df$var4, function(x) paste0("<a href=\"", x, '\">link</a>'))
datatable(
escape = FALSE,
df[var3 != "NA", c("var1", "var2", "var3", "var4", "var6")],
options = list(
scrollX = TRUE,
autoWidth = TRUE,
columnDefs = list((list(targets = c(1, 2), visible = TRUE, width = "5%")), (list(targets = c(3), visible = TRUE, width = "80%")), (list(targets = c(4, 5), visible = TRUE, width = "5%")))
)
)
这是我的第一个问题,所以如果我做错了什么请告诉我。
几天来,我一直在尝试在 Shiny App 中格式化 table,我尝试了所有方法,但我完全卡住了。
我有一个 table,理想情况下应该包括 14 列,其中大部分可能非常窄。但是,有 2 列包含长字符串,一列包含普通文本,另一列包含 URLs(文本列中信息的来源)。我希望第一个很宽,以便文本易于阅读,并且我不太关心 URL 列。我在某处读到 datatable 会自动尝试使列适合最长的单词,我发现这可能是这里的问题,因为无论我如何尝试设置列宽,URL 列都会结束向上很宽,其他的(包括文本列)很窄。但我想我可能有 2 个不同的问题:
问题 1:
我试图生成一个最小的可重现示例,但我发现确实是 URL 列搞乱了所有内容。
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by="days"), each=5 )
var2 <- rep(c("a", "b", "c", "d", "e"), each=10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA,8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
selection <- datatable(
df[var3!="NA", c("var1", "var2", "var3", "var4", "var6")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1,2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='80%')), (list(targets=c(4,5), visible=TRUE, width='5%')))))
截图:https://i.ibb.co/qkxw6Hm/Screenshot-from-2022-02-07-12-20-57.png
...而如果我不包含 URL 列:
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by="days"), each=5 )
var2 <- rep(c("a", "b", "c", "d", "e"), each=10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA,8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
selection <- datatable(
df[var3!="NA", c("var1", "var2", "var3", "var6")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1,2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='85%')), (list(targets=c(4), visible=TRUE, width='5%')))))
截图:https://i.ibb.co/rsgvD2b/Screenshot-from-2022-02-07-12-24-35.png
你对如何处理这个问题有什么建议吗?有没有一种方法可以在数据table 中格式化URLs,这样您就只会将短文本显示为可点击的link?还是有什么办法可以强制DT在“字”长的情况下挤列?
问题 2:
实际上,我已经放弃并决定删除带有 URL 的专栏并告诉 reader 如果他们想查看源代码,他们应该下载 .csv 文件。但是在我真正的 Shiny App 中设置列宽无论如何都不起作用。这是我实际 table 的代码,没有 URL 列:
output$selection <- renderDT(DT::datatable(
df[country==input$selection&change!="NA", c("date", "country", "change", "strictest_night", "strictest_day", "least_strict_night", "least_strict_day", "stayhome_day", "stayhome_night", "walk_day", "walk_night", "leave_municip", "outside_masks", "difference_with_oxcgrt")],
options=list(
scrollX=TRUE,
autoWidth=TRUE,
columnDefs=list((list(targets=c(1, 2), visible=TRUE, width='5%')), (list(targets=c(3), visible=TRUE, width='35%')), (list(targets=c(4:14), visible=TRUE, width='5%'))))))
下面是我在 UI 中调用 table 的方式:
selectInput("selection","select country/territory", choices=unique(df$country)),
tags$style(HTML("
.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, .dataTables_wrapper .dataTables_paginate {
color: #ffffff;
}
thead {
color: #ffffff;
}
"
)),
DTOutput("selection")
它在主面板中,上面有一个标签集面板,但我认为这无关紧要。我认为错误可能出在 HTML 样式代码中,因为坦率地说,我只是从某个地方复制了它。但是我把它注释掉了,我仍然有同样的问题。那可能是什么问题呢?我的列太多了吗?
下面是 table 的样子:https://i.ibb.co/XZ6hNH5/Screenshot-from-2022-02-07-13-07-43.png
非常感谢!
已找到解决方案: danlooo 已经回答了问题1。再次感谢!对于问题 2,我在这里找到了解决方案:Setting column width in R Shiny DataTable does not work in case of lots of column DT输出本身。我认为指定主面板宽度就足够了,但事实并非如此。我保留了所有内容,只是在 UI 中调用 table 时添加了一个宽度参数: DTOutput("selection", width="2000px") ... 它有效!
如果您使用 datatable(escape = FALSE)
:
library(data.table)
library(DT)
var1 <- rep(seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by = "days"), each = 5)
var2 <- rep(c("a", "b", "c", "d", "e"), each = 10)
var3 <- c(rep(NA, 10), "This is a non-empty entry.", rep(NA, 5), "yet another text. oh wow, this one is long. in the real world, there are even longer texts,", rep(NA, 2), "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", "Every 60 seconds in Africa a minute passes", rep(NA, 20), "some more dummy text", rep(NA, 8))
var4 <- c(rep(NA, 10), " rep(NA, 5), " rep(NA, 2), "https://www.youtube.com/watch?v=sAn7baRbhx4", "https://www.timeanddate.com/weather/antarctica", rep(NA, 20), "https://www.theguardian.com/football/live/2022/feb/06/senegal-v-egypt-africa-cup-of-nations-final-live-score-updates", rep(NA, 8))
var5 <- c(1:50)
var6 <- c(21:70)
df <- data.table(var1, var2, var3, var4, var5, var6)
# Transform text to HTML
df$var4 <- sapply(df$var4, function(x) paste0("<a href=\"", x, '\">link</a>'))
datatable(
escape = FALSE,
df[var3 != "NA", c("var1", "var2", "var3", "var4", "var6")],
options = list(
scrollX = TRUE,
autoWidth = TRUE,
columnDefs = list((list(targets = c(1, 2), visible = TRUE, width = "5%")), (list(targets = c(3), visible = TRUE, width = "80%")), (list(targets = c(4, 5), visible = TRUE, width = "5%")))
)
)