Home > database >  Add missing values in vector
Add missing values in vector

Time:12-15

I have the following vector <-c ("1.2", "1.11", "5.3", "5.5") and I want to complete it so that the output is

1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 5.1, 5.2, 5.3, 5.4, 5.5

You see, 1.11 is higher than, for example, 1.5 because it is the 11th element of 1.

It is basically grouped and sorted by the number before the floating point and then sorted by the number after the floating point with added values. Always start with a .1

I tried using seq, but of course it does not work since the digits 1.3 would be bigger than 1.11.

CodePudding user response:

A data.table option:

library(data.table)
as.data.table(tstrsplit(x, "\\."))[, .(V2 = seq_len(max(as.integer(V2)))), by = V1
                                   ][, paste(V1, V2, sep = ".")]
# [1] "1.1"  "1.2"  "1.3"  "1.4"  "1.5"  "1.6"  "1.7"  "1.8"  "1.9"  "1.10" "1.11" "5.1"  "5.2"  "5.3"  "5.4"  "5.5" 

Using pipes:

tstrsplit(x, "\\.") |>
  as.data.table() |>
  DT(, .(V2 = seq_len(max(as.integer(V2)))), by = V1) |> 
  DT(, paste(V1, V2, sep = "."))

CodePudding user response:

A base R solution (if you want a vector simply use unlist)

mapply(
    function(x,y){
      paste0(
        as.numeric(strsplit(x,"\\.")[[1]][1]),
        ".",
        seq(1,as.numeric(strsplit(y,"\\.")[[1]][2]),1)
      )
    },
    vector[seq(1,length(tmp),2)],
    vector[seq(2,length(tmp),2)]
  )

$`1.2`
 [1] "1.1"  "1.2"  "1.3"  "1.4"  "1.5"  "1.6"  "1.7"  "1.8"  "1.9"  "1.10" "1.11"

$`5.3`
[1] "5.1" "5.2" "5.3" "5.4" "5.5"

CodePudding user response:

Here might be one base R code you can use (I used v instead of vector to avoid colliding with the built-in function vector)

do.call(
  paste,
  c(rev(
    stack(
      lapply(
        split(
          gsub(".*\\.", "", v),
          gsub("\\..*", "", v)
        ),
        function(x) {
          seq(max(as.integer(x)))
        }
      )
    )
  ),
  sep = "."
  )
)

which gives

 [1] "1.1"  "1.2"  "1.3"  "1.4"  "1.5"  "1.6"  "1.7"  "1.8"  "1.9"  "1.10"
[11] "1.11" "5.1"  "5.2"  "5.3"  "5.4"  "5.5"

CodePudding user response:

An option that pastes sequences in a by.

do.call(rbind.data.frame, strsplit(vector, '\\.')) |>
  (\(s) by(s, s[, 1], \(z) {
    Reduce(\(x, y) paste(y, x, sep='.'), z[1], seq(max(as.numeric(z[, 2]))))
    }))() |>
  unlist() |> unname()
# [1] "1.1"  "1.2"  "1.3"  "1.4"  "1.5"  "1.6"  "1.7"  "1.8"  "1.9"  "1.10" "1.11"
# [12] "5.1"  "5.2"  "5.3"  "5.4"  "5.5" 
  •  Tags:  
  • r
  • Related