关于列表:交错嵌套在r中的向量,其中字符串填充基于最内层嵌套中的最大nchar

interleave nested ist of vectors in r with string padding based on max nchar in innermost nest

我在R中有一个向量嵌套列表,其中每个向量有不同的元素计数,每个元素包含一个长度不同的字符串,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 x <- list(
    A=list(
     c("11","11","11111","111","1111111111","11","11"),
     c("11","1111","11","111","11","111"),
     c("1111","111","1111") ),
    B=list(
     c("000","00","0","00","00000","00"),
     c("00","000","00","0000","0"),
     c("0000000","00","00") ) )

> x
$A
$A[[1]]
[1]"11"        "11"        "1111"      "111"       "1111111111""11"        "11"        

$A[[2]]
[1]"11"  "1111""11"  "1111""11"  "111"

$A[[3]]
[1]"1111""111" "1111"


$B
$B[[1]]
[1]"000"  "00"   "0"    "00"   "00000""00"  

$B[[2]]
[1]"00"  "000" "00"  "0000""0"  

$B[[3]]
[1]"0000000""00"     "00"

第一步:我想把每个嵌套列表的第n个元素以交错的方式打印出来,每个嵌套列表的第n个元素位于第n行,其中第n行的奇数元素来自A,偶数元素来自B,例如第一行将是

11000110011111011100111111111100000110011

第2步:我想在A和B嵌套列表中,基于该位置的max nchar为每个元素分别填充空格,因此在这个示例中,对于列表A,第一个元素的max nchar为4,第二个元素的max nchar为4,第三个元素的max nchar为5,第四个元素的max nchar为3等,但是对于B,第一个元素的max nchar为5等。为7,对于第二个为3等,所需输出为:

1
2
3
"11  000    11  00 111110 11100  11111111110000011 0011"
"11  00     111100011   00111000011        0    111"
"11110000000111 00 1111 00"

尝试调查时,我在交错两个列表时发现了这一点,但它不会交错列表的嵌套部分:

1
c(rbind(x$A,x$B))

产量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> c(rbind(x$A,x$B))
[[1]]
[1]"11"        "11"        "1111"      "111"       "1111111111""11"        "11"        

[[2]]
[1]"000"  "00"   "0"    "00"   "00000""00"  

[[3]]
[1]"11"  "1111""11"  "1111""11"  "111"

[[4]]
[1]"00"  "000" "00"  "0000""0"  

[[5]]
[1]"1111""111" "1111"

[[6]]
[1]"0000000""00"     "00"

但是我需要一些东西来交错内在的元素,也需要填充它们,而且我不能用lapply/sapply/apply等方法来缠绕我的大脑。

在我的数据长度(x$a)==长度(x$b)和长度(x$a[[n]])==长度(x$b[[n]])+1中,没有遗漏的元素用于交错


用足够数量的""拉长每个元件应该是方便的,以便方便地找到最大元件方向的nchar,随后,rbind交叉连接到连接柱中:

1
2
n = do.call(max, lapply(x, lengths))
x2 = lapply(x, function(ab) lapply(ab, function(x) c(x, rep_len("", n - length(x)))))

然后找出每个元素的"平行"最大值nchar

1
ncx2 = lapply(x2, function(x) unlist(.mapply(max, lapply(x, nchar), NULL)))

以及右垫和空格,相应地:

1
x3 = Map(function(elt, nc) lapply(elt, function(x) sprintf("%-*s", nc, x)), x2, ncx2)

最后,使用rbind的替代方法交错元素,并适当地格式化输出:

1
2
3
4
5
6
7
8
9
.mapply(function(...) trimws(paste(c(rbind(...)), collapse ="")), x3, NULL)
#[[1]]
#[1]"11  000    11  00 111110 11100  11111111110000011 0011"
#
#[[2]]
#[1]"11  00     111100011   00111000011        0    111"
#
#[[3]]
#[1]"11110000000111 00 1111 00"

如果x只有两个元素,那么存储a = x$A; b = x$B和代码的重复部分会更方便,以避免额外嵌套的lapply/mapply编译调用。


我们可以尝试

1
2
3
4
5
6
7
8
9
10
11
12
lapply(seq(lengths(x)[1]), function(i)  {
        x1 <- c(x[[1]][i], x[[2]][i])
       x2 <- c(do.call(rbind, lapply(x1, `length<-`, max(lengths(x1)))))
       paste(replace(x2, is.na(x2),""), collapse="")})
#[[1]]
#[1]"11000110011111011100111111111100000110011"

#[[2]]
#[1]"1100111100011001110000110111"

#[[3]]
#[1]"1111000000011100111100"

如果我们使用包,那么可以使用transpose(来自purrr)和stri_list2matrix(来自stringi)。

1
2
3
4
5
6
7
8
9
10
11
12
13
library(purrr)
library(stringi)
transpose(x) %>%
        map(stri_list2matrix, byrow=TRUE, fill="") %>%
        map(paste, collapse="")
#[[1]]
#[1]"11000110011111011100111111111100000110011"

#[[2]]
#[1]"1100111100011001110000110111"

#[[3]]
#[1]"1111000000011100111100"

第二步,我们认为这是可行的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lst2 <- lapply(x, function(y) {l1 <- lapply(y, nchar)
    do.call(pmax, c(lapply(l1, `length<-`, max(lengths(l1))), na.rm=TRUE))})
lst3 <- lapply(transpose(x), function(x) Map(function(y, z)
       do.call(c, lapply(seq_along(y), function(i)
       formatC(y[i], width = z[1:length(y)][i], flag ="-"))), x, lst2))
lapply(lst3, function(x) paste(stri_list2matrix(x, fill="", byrow=TRUE), collapse=""))
#[[1]]
#[1]"11  000    11  00 111110 11100  11111111110000011 0011"

#[[2]]
#[1]"11  00     111100011   00111000011        0    111"

#[[3]]
#[1]"11110000000111 00 1111 00"