【问题标题】:Split Variable and insert NA's in between拆分变量并在其间插入 NA
【发布时间】:2015-05-26 22:48:47
【问题描述】:

我有一个看起来像这样的变量:

Var
[1] 3, 4, 5     2, 4, 5     2, 4     1, 4, 5

我需要将其拆分为如下所示的数据框:

V1   V2   V3   V4   V5
NA   NA   3    4    5
NA   2    NA   4    5
NA   2    NA   4    NA
1    NA   NA   4    5

不幸的是,我找不到解决我问题的帖子。有谁知道我该怎么做? 非常感谢您!

编辑:我根据您的回答找到了解决方案并将其发布在下面。

Edit2:我使用 Ananda 的解决方案提高了代码的效率。

【问题讨论】:

  • Varlist 还是 vector 还是什么?您的示例不可重现。是c(3,4,5,2,4,5,2,4,1,4,5) 还是list(c(3,4,5),c(2,4,5),c(2,4),c(1,4,5)) 还是c("3, 4, 5 2, 4, 5 2, 4 1, 4, 5")

标签: r variables split dataframe


【解决方案1】:

使用矩阵索引:

Var <- list(c(3,4,5),c(2,4,5),c(2,4),c(1,4,5))
unVar <- unlist(Var)
out <- matrix(NA, nrow=length(Var), ncol=max(unVar))

out[cbind(rep(seq_along(Var),sapply(Var,length)),unVar)] <- unVar
# and if you're using the new version of R, you can simplify a little:
out[cbind(rep(seq_along(Var),lengths(Var)),unVar)] <- unVar

#     [,1] [,2] [,3] [,4] [,5]
#[1,]   NA   NA    3    4    5
#[2,]   NA    2   NA    4    5
#[3,]   NA    2   NA    4   NA
#[4,]    1   NA   NA    4    5

【讨论】:

    【解决方案2】:

    从 OP 的回答来看,“var”是一个字符串,例如:

    var <- c("3, 4, 5", "2, 4, 5", "2, 4", "1, 4, 5")
    

    如果是这样,你可以考虑我的“splitstackshape”包中的cSplit_e

    library(splitstackshape)
    cSplit_e(data.frame(var), "var", ",", mode = "value", drop = TRUE)
    #   var_1 var_2 var_3 var_4 var_5
    # 1    NA    NA     3     4     5
    # 2    NA     2    NA     4     5
    # 3    NA     2    NA     4    NA
    # 4     1    NA    NA     4     5
    

    如果它是list,正如其他答案所假设的那样,您可以在支持cSplit_e 的“splitstackshape”中使用(非导出的)numMat 函数。

    var <- list(c(3,4,5), c(2,4,5), c(2,4), c(1,4,5))
    splitstackshape:::numMat(var, mode = "value")
    #       1  2  3 4  5
    # [1,] NA NA  3 4  5
    # [2,] NA  2 NA 4  5
    # [3,] NA  2 NA 4 NA
    # [4,]  1 NA NA 4  5
    

    在后台,numMat 与@thelatemail 的答案中使用的方法非常相似。


    如果你有 -99 代表 NA 并且你想排除它们,你可以尝试:

    var <- c("3, 4, 5", "2, -99, 4, 5", "2, 4", "1, 4, 5, -99")
    splitstackshape:::numMat(
      lapply(strsplit(var, ","), function(x) as.numeric(x)[as.numeric(x) > 0]), 
      mode = "value")
    #       1  2  3 4  5
    # [1,] NA NA  3 4  5
    # [2,] NA  2 NA 4  5
    # [3,] NA  2 NA 4 NA
    # [4,]  1 NA NA 4  5
    

    【讨论】:

    • 非常感谢!您的第一个解决方案效果很好,使我的代码更短!
    【解决方案3】:
     Var <- list(c(3, 4, 5), c(2, 4, 5), c(2, 4), c(1, 4, 5))
     M <- matrix(NA, nrow=length(Var), ncol=max(sapply(Var,max)))
     for( L in seq(Var) ) { M [ cbind( rep( L, length(Var[[L]])), Var[[L]]) ] <- Var[[L]]}
     M
         [,1] [,2] [,3] [,4] [,5]
    [1,]   NA   NA    3    4    5
    [2,]   NA    2   NA    4    5
    [3,]   NA    2   NA    4   NA
    [4,]    1   NA   NA    4    5
    

    就我个人而言,我的投票推荐是 thelatemail 的版本,它基本上与此同构。

    【讨论】:

      【解决方案4】:

      如果 Var 只是一个向量,那么我将执行以下操作:

      Var = c(3,4,5,2,4,5,2,4,1,4,5)
      RowIdx = c(rep(1,3),rep(2,3),rep(3,2),rep(4,3))
      DF = matrix(NA,nrow=4,ncol=5)
      
      for (idx in 1:length(Var)){
        DF[RowIdx[idx],Var[idx]] = Var[idx]
      }
      

      当然,如果您有更多数据,您可能希望找到一种以更自动化的方式生成行索引的方法

      【讨论】:

        【解决方案5】:

        根据您的回复,我设法找到了解决方案!我的最终解决方案如下所示:

        # I had the additional problem that my variable was a factor, therefore I had to transform it first.
        df <- data.frame(Var)
        Var <- lapply(strsplit(as.character(df$Var), ", "), "[")
        for(i in 1:length(Var)){
          Var[[i]] <- as.numeric(Var[[i]]) 
        }
        
        # Then I created a matrix based on thelatemails and BondedDusts approach.
        M <- matrix(NA, nrow=length(Var), ncol=max(sapply(Var,max)))
        
        # Additionally, I had the problem that there were some lines with a single -99, which indicates a missing value for the complete line. I had some problems with this negative value. For this reason, I assigned NA's first.
        for(i in 1:length(Var)){
          Var[[i]][Var[[i]] == -99] <- NA
        }
        
        # Final assignment like suggested by BonedDust.
        for( L in seq(Var) ) { M [ cbind( rep( L, length(Var[[L]])), Var[[L]]) ] <- Var[[L]]}
        M
        

        我不确定这是否是最快的解决方案,但现在一切正常!非常感谢您提供快速而广泛的答案!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-09
          相关资源
          最近更新 更多