[英]Create a list of vectors from a vector where n consecutive values are not 0 in R
所以我有这个向量:
a = sample(0:3, size=30, replace = T)
[1] 0 1 3 3 0 1 1 1 3 3 2 1 1 3 0 2 1 1 2 0 1 1 3 2 2 3 0 1 3 2
我想要的是一个向量列表,其中包含由 n 0 分隔的所有元素。 所以在这种情况下,n = 0(连续值之间不能有任何 0),这将给出:
res = c([1,3,3], [1,1,1,3,3,2,1,1,3], [2,1,1,2]....)
但是,如果我将其设置为 2,我想灵活地控制 n 参数,例如:
b = c(1,2,0,3,0,0,4)
仍然会导致这样的结果
res = c([1,2,3],[4])
在尝试计算 0 的数量时,我尝试了很多使用 for 循环中的 while 循环的方法。 但我就是无法实现。
更新
我试图在此处以更真实的设置发布问题: 根据 R 中另一列中的连续计数灵活计算列
谢谢大家的帮助。 以我有限的知识,我似乎无法将您的帮助付诸实践。
这是一个基本的 R 选项,在一般情况下使用rle
+ split
,即b
中的值不限于0
到3
。
with(
rle(with(rle(b == 0), rep(values & lengths == n, lengths))),
Map(
function(x) x[x != 0],
unname(split(b, cut(seq_along(b), c(0, cumsum(lengths))))[!values])
)
)
这给出(假设n=2
)
[[1]]
[1] 1 2 3
[[2]]
[1] 4
如果您的值在 ragne 0
到9
之间,您可以尝试下面的代码
lapply(
unlist(strsplit(paste0(b, collapse = ""), strrep(0, n))),
function(x) {
as.numeric(
unlist(strsplit(gsub("0", "", x), ""))
)
}
)
这也给出了
[[1]]
[1] 1 2 3
[[2]]
[1] 4
我还想用 DescTools 的 function SplitAt
粘贴一个有用的解决方案:
SplitAt(a, which(a==0)) %>% lapply(., function(x) x[which(x != 0)])
其中 a 是您的初始向量。 它为您提供了一个列表,其中每个条目都包含零之间的一对数字:
如果您添加另一个带有空字符的 SplitAt,您可以在子列表之后创建子列表并将其拆分为任意数量的子列表:例如:
n <- 4
SplitAt(a, which(a==0)) %>% lapply(., function(x) x[which(x != 0)]) %>% SplitAt(., n)
给你:
set.seed(1)
a <- sample(0:3, size=30, replace = T)
a
[1] 0 3 2 0 1 0 2 2 1 1 2 2 0 0 0 1 1 1 1 2 0 2 0 0 0 0 1 0 0 1
a2 <- paste(a, collapse = "") # Turns into a character vector, making it easier to handle patterns.
a3 <- unlist(strsplit(a2, "0")) # Change to whatever pattern you want, like "00".
a3 <- a3[a3 != ""] # Remove empty elements
a3 <- as.numeric(a3) # Turn back to numeric
a3
[1] 32 1 221122 11112 2 1 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.