【问题标题】:R - Exporting a List through Openxlsx with Separately Sorted Columns Placing NA Values LastR - 通过 Openxlsx 导出列表,其中单独排序的列将 NA 值放在最后
【发布时间】:2021-11-10 18:26:32
【问题描述】:

找到解决方案!滚动到最后看看我做了什么。希望这个功能可以帮助其他人。


TLDR:我有一个列表:https://i.stack.imgur.com/7t6Ej.png

我需要对它做这样的事情

lapply(irabdf, function(x) c(x[!is.na(x)], x[is.na(x)]))

但我需要这个函数单独对列表的每个元素执行此操作,而不是删除列名。目前,我可以让它从最低到最高排序,但它会将所有内容移动到单个列中并删除列名。


我在 R 中有一个列表,我使用 Openxlsx 包将其导出为 XLS 文件。我拥有功能上所需的一切,但我的 P.I 要求我将每一列从最低到最高排序以供审阅者使用,因为有很多空单元格使文档看起来很有趣。我正在尝试在 R 中添加此功能,这样我就不需要手动完成了。所有列都是从单独的 .csv 文件创建的,行并不重要。

名单:https://i.stack.imgur.com/7t6Ej.png

生成的 XLSX 文件如下所示: https://i.stack.imgur.com/ftg00.png.

这些列不是空白的,数据只是进一步向下。

我写文件的代码:

wb <- createWorkbook()
lapply(names(master), function(i){
  addWorksheet(wb=wb, sheetName = names(master[i]))
  writeData(wb, sheet = i, master[[i]])
  addFilter(wb, sheet = i, rows = 1, cols = 1:(a))
  })
#Save Workbook
saveWorkbook(wb, saveFile, overwrite = TRUE)

a = 这个值是通过(length(unique(x))得到的。X是一个变量的级别。

我有什么:

Column1, Column2, Column3, Column4
1. 1        NA       NA       NA
2. 2        NA       NA       NA
3. NA       3        NA       NA
4. NA       4        NA       NA
5. NA       NA       5        NA
6. NA       NA       6        NA
7. NA       NA       NA       7
8. NA       NA       NA       8

我想要什么:

Column1, Column2, Column3, Column4
1. 1        3        5        7
2. 2        4        6        8
3. NA       NA       NA       NA
4. NA       NA       NA       NA
5. NA       NA       NA       NA
6. NA       NA       NA       NA
7. NA       NA       NA       NA
8. NA       NA       NA       NA

实际文件中每列有 1,000 行和 100 个空白单元格。该解决方案将在 XLSX 文件的所有选项卡中复制此内容。

我尝试过的: 在此脚本的先前版本中,我能够做到这一点。我有单独的 df,它们通过用户对话选项分配了名称。这是我曾经这样做的代码示例。

irabdf <- masterdf %>%
    filter(Fluorescence == "Infrared") %>%
    select(mean, Conditions) %>%
    mutate(row = row_number()) %>%    
    spread(Conditions, mean) %>%
    select(!row)

irabdf <- lapply(irabdf, function(x) c(x[!is.na(x)], x[is.na(x)])) %>%  ## Move NAs to the bottom of the df
         data.frame()

# Create a blank workbook
WB <- createWorkbook()

# Add some sheets to the workbook
addWorksheet(WB, gab)
addWorksheet(WB, rab)
addWorksheet(WB, irab)

# Write the data to the sheets
writeData(WB, sheet = gab, x = gabdf)
writeData(WB, sheet = rab, x = rabdf)
writeData(WB, sheet = irab, x = irabdf)

# Reorder worksheets
worksheetOrder(WB) <- c(1:3)

# Export the file
saveWorkbook(WB, saveFile)

现在我已经删除了用户界面并使用了一个列表,我不能再这样做了。我还尝试了无数其他使用 lapply 的方法。

如果您需要更多信息,请询问。

提前感谢您的帮助!


09/21

我想我已经接近了,但我仍然没有解决问题。

当我使用这段代码时

list <- lapply(master[[1]],
     function(x) c(x[!is.na(x)], x[is.na(x)]))

我得到了我想要的结果,但最终丢失了第一个元素。如果我可以保留第一个元素并将其应用于我的整个列表,那应该可以解决问题。


09/22

我发现了一些有用的东西!但是,它不是动态的。如果有人可以帮助我在此列表的所有元素中循环此函数(或知道更好的解决方案),请告诉我。

list1 <- lapply(master[[1]],
     function(x) c(x[!is.na(x)], x[is.na(x)]))

list1 <- data.frame(list1)

master[[1]] <- list1

我需要将 list1 指定为 df,以便在我的 XLSX 输出中维护我的列名。


09/22 - 2

好的,我的脚本完全按照我的意愿执行。但是,它并不漂亮,也不是“非常”动态的。

+rep 给任何可以帮助我将其转换为漂亮的循环的人!

    if (b >= 1) {
    list1 <- lapply(master[[1]],
    function(x) c(x[!is.na(x)], x[is.na(x)]))
    list1 <- data.frame(list1)
    master[[1]] <- list1
}
if (b >= 2) {   
    list2 <- lapply(master[[2]],
    function(x) c(x[!is.na(x)], x[is.na(x)]))
    list2 <- data.frame(list2)
    master[[2]] <- list2
}

等... x12

b 在这里的值为 12。但是,它实际上可以是任何数字。


09/22 - 3

好吧,我想通了。我创建了以下循环来完成我需要做的事情,并且一切似乎都运行良好。我的一部分想要快乐地尖叫。

for (i in 1:length(unique(masterdf$ABwant))) {
  if (i >= 1)
  list.i <- lapply(master[[i]],
    function(x) c(x[!is.na(x)], x[is.na(x)]))
    list.i<- data.frame(list.i)
    master[[i]] <- list.i
}

我将在本周的剩余时间里保持这个线程打开,如果有人有更好的解决方案,我会接受它并给你一些代表。否则,GG。

【问题讨论】:

  • 不幸的是,我还没有找到解决这个问题的方法。如果有人可以提供帮助,我将不胜感激。
  • 您是否有可以共享的数据来复制问题?我怀疑这是问题所在,但是 x 的长度是多少?如果您只想将过滤器添加到行的顶部,您可以使用 writeDataTable 而不是 writeData 和 addfilter 命令。 writeDataTable 会自动将过滤器添加到第一行,您无需指定列数
  • 你好乔尼,谢谢你的回复。 X 是变量的唯一级别数。而过滤器命令只是我添加的东西,以便在此期间让我的生活更轻松。一旦我得到正确排序的东西,我会删除它。目前,这按预期工作。如果我的问题不清楚,我会很乐意详细说明。让我知道!最终,我只是不想在生成的 XLSX 文件中有空格。
  • 您能详细说明我需要分享的内容吗?您想查看更多我正在生成的列表吗?
  • 我已经接近但还没有得到解决方案。我已经更新了我的帖子。

标签: r openxlsx


【解决方案1】:

这是我用来创建我想要的循环的代码。

 for (i in 1:length(unique(masterdf$ABwant))) {
  if (i >= 1)
  list.i <- lapply(master[[i]],
    function(x) c(x[!is.na(x)], x[is.na(x)]))
    list.i<- data.frame(list.i)
    master[[i]] <- list.i
}

使用 OpenXLSX,我能够使用此循环创建一个 Excel 文件,该文件对每个抗体都有一个单独的选项卡,并且所有列都按 NA 值排序在底部。

### Creating the Excel file
wb <- createWorkbook()
lapply(names(master), function(i){
  addWorksheet(wb=wb, sheetName = names(master[i]))
  writeData(wb, sheet = i, master[[i]])
     # Saving the Excel file
saveWorkbook(wb, saveFile, overwrite = TRUE)

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2015-02-18
    • 2023-03-11
    相关资源
    最近更新 更多