我有一组字母数字向量:
lst <- list(c("三垣3-19", "6", "81497", "79992", "79101",
"77760", "75973", "75411", "74666"), c("蒼龍1-01", "2", "66249", "65474", "66803", "64238"), c("蒼龍1-02", "1", "64238"), "蒼龍1-03")
[[1]]
[1] "三垣3-19" "6" "81497" "79992"
[5] "79101" "77760" "75973" "75411"
[9] "74666"
[[2]]
[1] "蒼龍1-01" "2" "66249" "65474"
[5] "66803" "64238"
[[3]]
[1] "蒼龍1-02" "1" "64238"
[[4]]
[1] "蒼龍1-03"
每个向量上的第二个数字(即6,2,1)表示连接星形的总线数,由它们的HIP编号一起给出。每对HIP编号表示在2颗星之间绘制的线。
因此81497 79992
中的[[1]]
意味着“在星号”81497“和”79992“之间划一条线,依此类推。
在连续线的情况下,例如[[1]]
,应重复“81497”和“74666”之间的数字,以便线条没有中断。
因此,在[[1]]
的情况下,应重复"79992" "79101" "77760" "75973" "75411"
以得到以下结果:
[[1]]
[1] "三垣3-19" "6" "81497" "79992"
[5] "79992" "79101" "79101" "77760"
[9] "77760" "75973" "75973" "75411"
[13] "75411" "74666"
[[2]]
[1] "蒼龍1-01" "2" "66249" "65474"
[5] "66803" "64238"
[[3]]
[1] "蒼龍1-02" "1" "64238" "64238"
[[4]]
[1] "蒼龍1-03"
由于每个列表上的第二个元素表示要绘制的总行数,因此可以对有效性测试进行编码以指示是否需要重复某些数字。因此6
中的[[1]]
意味着应该有6对(即6 * 2 = 12个元素)的HIP数字。当有效性测试失败时,我希望R为我重复第三个和最后一个元素之间的数字,以便绘制连续线。
我设法解决的部分解决方案如下:
lapply(lst, function(x) x[2]) == (lengths(lst)-2)/2
[1] FALSE TRUE FALSE NA
这会测试HIP值的有效性。只有[[2]]
符合原始列表中的说明。 [[1]]
和[[3]]
将是我们需要处理的向量。
要在某个向量之间重复单个值,我可以这样做:
> x <- c(1,2,3,4,5)
> x[2:4] <- lapply(x[2:4], function(x) rep(x, 2))
> unlist(x)
[1] 1 2 2 3 3 4 4 5
但是,因为lst
是一个列表,我不能这样做:
lst[2:4] <- lapply(lst[2:4], function(x) rep(x, 2))
获得相同的结果。需要由lengths(lst)
指定结束号码(在这种情况下为4)的事实使问题更加复杂。
我想最终的代码是一个ifelse()
函数来加入上面描述的两个函数。
澄清规则:
每个向量的第二个元素表示绘制直线的所需数量的不同HIP对。
[[2]]
是有效的,因为后面有两对数字,它符合第二个元素中给出的值,因此不需要重复这些数字。
在这种情况下,线条很可能形成十字形,而不是连续线条。因此,规则应仅适用于连续行,例如[[1]]
。
对于[[3]]的情况,由于只有一个点,因此通常会重复该数字,以便第二个元素给出的有效性得以维持。
BUG INQUIRY
@TUSHAr:当向量中的元素包含非数字值时,您的代码似乎会生成NA
个值。
lst <- list(c("三垣3-19", "6", "81497", "79992A", "79101",
"77760", "75973A", "75411", "74666"), c("蒼龍1-01", "2", "66249", "65474", "66803B", "64238"), c("蒼龍1-02", "1", "64238"), "蒼龍1-03")
使用上述数据运行代码,您将获得:
[[1]]
[1] "三垣3-19" "6" "81497" NA NA
[6] "79101" "79101" "77760" "77760" NA
[11] NA "75411" "75411" "74666"
[[2]]
[1] "蒼龍1-01" "2" "66249" "65474" NA
[6] "64238"
[[3]]
[1] "蒼龍1-02" "1" "64238" "64238"
[[4]]
[1] "蒼龍1-03"
造成这种情况的原因是什么?有办法解决这个问题吗?
答案 0 :(得分:1)
将vector
中每个lst
的第一个值存储在单独的变量id
中,以避免在处理过程中出现不必要的子集。
id = lapply(lst,function(t){t[1]})
删除了已存储在id
。
lst = lapply(lst,function(t){
t=t[-1]
#if(length(t)>0){
# as.integer(t)
#}
})
循环处理已处理的lst
对象:
temp = lapply(lst,function(t){
#Use the first value as the desired number of pairs in `reqdpairs`
reqdpairs = as.numeric(t[1])
#remove the first values so that `t` only contains HIP numbers.
t=t[-1]
#calculate existing number of pairs for case [[2]] such that if all conditions are satisfied we don't do any processing
noofpairs = floor(length(t)/2)
#check if `t` contains values after removing the first element. The `else` part covers the case [[3]]
if(length(t)>1){
#If `noofpairs` is not equal to `reqdpairs` use `rep` on the inner elements (**excluding the first and last element**) of the vector.
if(noofpairs!=reqdpairs){
pairs=c(reqdpairs,t[1],rep(t[-c(1,length(t))],each=2),t[length(t)])
}else{
#In this case no processing is required so we just merge the reqdpairs with `t` as it is
pairs=c(reqdpairs,t)
}
}else if(length(t)==1){
pairs=rep(t[1],times=2)
pairs=c(reqdpairs,pairs)
}else{
pairs=NULL
}
pairs=as.character(pairs)
}
)
此步骤是将id
与temp
合并以实现所需的输出格式。基本上只是一个连接步骤。
mapply(function(x,y){c(x,y)},id,temp)
#[[1]]
#[1] "三垣3-19" "6" "81497" "79992" "79992" "79101" "79101" "77760" "77760" "75973"
#[11] "75973" "75411" "75411" "74666"
#[[2]]
#[1] "蒼龍1-01" "2" "66249" "65474" "66803" "64238"
#[[3]]
#[1] "蒼龍1-02" "1" "64238" "64238"
#[[4]]
#[1] "蒼龍1-03"