R - 通过 Openxlsx 导出列表,其中单独排序的列将 NA 值放在最后

R - Exporting a List through Openxlsx with Separately Sorted Columns Placing NA Values Last

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


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 给任何可以帮助我将其转换成漂亮的 lapply 循环的人!

    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.

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

 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)