简体   繁体   English

在 R 中使向量长度相同

[英]Make vectors same length in R

This task is not as simple as the title suggests.这项任务并不像标题所暗示的那么简单。 It's better for me to just use a lame example to explain what I want.我最好只用一个蹩脚的例子来解释我想要什么。 I have two vectors x and y...我有两个向量 x 和 y ...

x <- c("Description 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","Tot") 
y <- c("Minutes","","","35","60 60 30","60 60","","15","60 60","440")
rbind(x,y)

x "Description 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" "Tot"
y "Minutes"                 ""                   ""               "35"             "60 60 30" "60 60"    ""   "15" "60 60" "440"

I need the minutes to align for the specific days from a pdf table.我需要分钟来对齐 pdf 表中的特定日期。 It helps to see what I want if you look at x and y combined together (above).如果您将 x 和 y 组合在一起(上图),则有助于了解我想要什么。 For each "column", if the minutes have more than one day above them, I need to shift the minutes to the last day.对于每个“列”,如果分钟超过一天,我需要将分钟移到最后一天。 For example, on days 18-22, we see there were 35 minutes for one of those days... I need to shift those 35 minutes to correspond to the 22nd day of the month.例如,在第 18-22 天,我们看到其中一天有 35 分钟……我需要将这 35 分钟移动到对应于该月的第 22 天。 For each day that doesn't have any minutes I need to give that day a value of NA.对于没有任何分钟的每一天,我需要给那一天一个 NA 值。 The result should look like the following...结果应如下所示...

result <- data.frame(rbind(seq(1:31),c(rep(NA,21),35,60,60,30,NA,60,60,15,60,60)))
result

X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
1  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
2 NA NA NA NA NA NA NA NA NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  35  60  60  30  NA  60  60  15  60  60

Any help appreciated!任何帮助表示赞赏!

Update:更新:

I was able to the solve the problem with the following code...我能够使用以下代码解决问题...

z <- rbind(x,y)
z <- z[,-ncol(z)]
result <- lapply(1:ncol(z),function(x){
    print(x)
    col <- z[,x]
    row1 <- do.call("c",str_extract_all(col[1],"\\(?[0-9,.]+\\)?"))
    row2 <- do.call("c",str_extract_all(col[2],"\\(?[0-9,.]+\\)?"))
    if(length(row2) == 0) {
        w <- rbind(row1,rep(NA,length(row1)))
    } else {
        w <- rbind(row1,c(rep(NA,length(row1)-length(row2)),row2))
    }
    w
})
do.call("cbind",result)

Would be interested in seeing other people'e solutions still.仍然有兴趣看到其他人的解决方案。

Here is another approach - see what you think.这是另一种方法 - 看看你的想法。

# First four lines are from your original post
x <- c("Description 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","Tot")
y <- c("Minutes","","","35","60 60 30","60 60","","15","60 60","440")
z <- rbind(x,y)
z <- z[,-ncol(z)]

# Function to extract numbers
match_fxn <- function(x) { 
  matches <- regmatches(x, gregexpr("[[:digit:]]+", x))
  as.numeric(unlist(matches))
}

# Create nested matrix of extracted numbers, 
mat <- apply(z, 1:2, match_fxn)

# Force lengths to be same between rows 1 and 2 (adds NAs)
min_list <- mapply(`length<-`, x = mat[2,], Var = lengths(mat[1,]))

# Sort so that NAs are in the beginning
min_sort <- lapply(min_list, function(x) c(x[is.na(x)], x[!is.na(x)]))

# Add rows 1 and 2 to show final result
rbind(unlist(mat[1,]), unlist(min_sort))

Output输出

     [,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]
[1,]    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
[2,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    35    60    60    30    NA    60    60    15    60    60

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM