首页 文章

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

提问于
浏览
0

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

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"

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

11000110011111011100111111111100000110011

step2:我想在A和B的嵌套列表中为每个元素填充基于max nchar的空格,所以在这个例子中,对于列表A,第一个元素的max nchar是4,最大nchar是第二个也是4,第三个的最大nchar是5,第四个的最大nchar是3等但是对于B,第一个元素的最大nchar是7,第二个是3等 . 所需的输出是:

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

试图调查我发现this交错两个列表,但它不会交错列表的嵌套部分:

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

产量

> 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 / rapply等 .

在我的数据 length(x$A) == length(x$B)length(x$A[[n]]) == length(x$B[[n]])+1 中,因此不存在用于交错的缺失元素

2 回答

  • 1

    使用足够数量的 "" 来扩展每个元素应该很方便,以便方便地找到最大元素 nchar ,然后, rbind 交错,如链接帖子中所示:

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

    然后找到每个元素的'parallel'最大值 nchar

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

    right-pad带空格,相应地:

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

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

    .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 compilcated调用 .

  • 0

    我们可以尝试

    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

    library(purrr)
    library(stringi)
    transpose(x) %>%
            map(stri_list2matrix, byrow=TRUE, fill="") %>%
            map(paste, collapse="")
    #[[1]]
    #[1] "11000110011111011100111111111100000110011"
    
    #[[2]]
    #[1] "1100111100011001110000110111"
    
    #[[3]]
    #[1] "1111000000011100111100"
    

    对于第二步,我们猜测这是有效的

    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"
    

相关问题