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中,没有遗漏的元素用于交错
用足够数量的
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))))) |
然后找出每个元素的"平行"最大值
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) |
最后,使用
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" |
如果
我们可以尝试
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" |
如果我们使用包,那么可以使用
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" |