R - 改变列表结构

R - alter list structure

我有一些文本数据在读入 R 后以下列格式呈现:

> lst <- list('A', c("", 'aa'), 'bb', 'cc', 'B', c("", 'aa'), 'bb', 'cc', 'dd')

[[1]]
[1] "A"

[[2]]
[1] ""   "aa"

[[3]]
[1] "bb"

[[4]]
[1] "cc"

[[5]]
[1] "B"

[[6]]
[1] ""   "aa"

[[7]]
[1] "bb"

[[8]]
[1] "cc"

[[9]]
[1] "dd"

有没有一种简单的方法可以更改此列表的结构,使用“”作为指示符,使紧接在“”之前的项目成为列表标题?

lst2 <- list(A=c('aa', 'bb', 'cc'), B=c('aa', 'bb', 'cc', 'dd'))

$A
[1] "aa" "bb" "cc"

$B
[1] "aa" "bb" "cc" "dd"

我们可以unlistlist转换为vector('v1'),然后根据空字符串的位置创建分组索引(!nzchar(v1)), 删除第一个元素并在末尾附加 FALSE ,得到累积和,以便该组从出现空字符串之前的位置开始。然后,我们在 tapply 中使用它,删除向量的第一个元素并使用 group by 操作获取向量的第一个元素,用于命名 'lst2'

v1 <- unlist(lst)
i1 <- cumsum(c(!nzchar(v1)[-1], FALSE))
lst2 <- tapply(v1, i1, FUN = function(x) x[-(1:2)])
names(lst2) <-   tapply(v1, i1, FUN = head, 1)
lst2
#$A
#[1] "aa" "bb" "cc"

#$B
#[1] "aa" "bb" "cc" "dd"

另一个可能的选择:

spl_vals <- c("")

idxs <- lapply(lst, function(x) as.numeric(any(spl_vals %in% x)))       #Find location of split values
c_idxs <- cumsum(idxs)                                                  #Use cumsum to group sets of values
c_idxs[which(idxs==1) - 1] <- 0                                         #Assign the value before each split to be 0. This will be the name of the element

spl <- split(lst, c_idxs)                                               #Split you list into (1) names of elements and (2) individual elements
newlist <- lapply(spl, function(x) unlist(x)[!unlist(x) %in% spl_vals]) #Remove any split values
nms <- names(newlist)                                                   #Extract names of list (this is just for shortening the next line of code)
setNames(newlist[nms[!nms %in% "0"]], newlist[["0"]])                   #Set names of elements

$A
[1] "aa" "bb" "cc"

$B
[1] "aa" "bb" "cc" "dd"

请注意,这不会从一开始就使用 unlist,因此如果您有多个拆分值并且您希望两个元素具有不同的类型(例如字符和整数),这会保留该类型。例如,使用:

lst <- list('A', c("", 'aa'), 'bb', 'cc', 'B', c(0, 1), 2, 3, 4)
spl_vals <- c("",0)

你得到:

$A
[1] "aa" "bb" "cc"

$B
[1] 1 2 3 4