R在嵌套列表

时间:2017-10-25 05:07:09

标签: r list vector

我有一组字母数字向量:

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"

造成这种情况的原因是什么?有办法解决这个问题吗?

1 个答案:

答案 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)
}
)

此步骤是将idtemp合并以实现所需的输出格式。基本上只是一个连接步骤。

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"