首页 文章

将具有连接索引和值的字符串转换为值向量

提问于
浏览
1

我有这样的数据框:

v2      v3
1.000   2:3,3:2,5:2,
2.012   1:5,2:4,6:3,

第二列v3由'index-value'对组成,每对由 , 分隔 .

在每个'index-value'对中, : 之前的数字是向量索引 . : 之后的数字是相应的值 . 例如 . 在第一行中,矢量索引是2,3和5,并且相应的值是3,2和2 .

未在字符串中表示的索引在结果向量中应具有值0 .

我希望将'index-value'向量转换为值向量 .

因此,对于超出预期结果的两个字符串是:

v2     v3
1.000  c(0,3,2,0,2,0)
2.012  c(5,4,0,0,0,3)

3 回答

  • 1

    我们使用 data.table 包只是为了使用它的 tstrsplit 函数 . 它删除了一个中间步骤 . 试试这个:

    require(data.table)
    df$v3<-lapply(
      lapply(strsplit(as.character(df$v3),",",fixed=TRUE),tstrsplit,":"),
       function(x) {res<-numeric(6);res[as.numeric(x[[1]])]<-as.numeric(x[[2]]);res})
    #     v2               v3
    #1 1.000      0,3,2,0,2,0
    #2 2.012      5,4,0,0,0,3
    
    • 我们首先使用逗号( , )拆分 v3 的每个元素

    • 然后我们再次使用 : 作为分隔符进行拆分;

    • 我们创建一个长度为6的数字向量;

    • 我们最终根据描述的逻辑填充值 .

  • 0

    我建议采用类似于@nicola建议的方法,但是,为了好玩,这里有一个替代方案 .

    使用 read.dcf ,用于读取"tag:value"类型数据 . 要获取所有"tags",请使用 fields 参数 . 您在对@nicola的评论中将此指定为1:6 . 此外,您需要用换行符( "\n" )替换"," .

    我们将所有这些存储在一个字符串中,以便 deparse textConnection will be able to handle it . 这个例子没有必要,但以防万一....

    str <- gsub(",", "\n", mydf$v3)
    x <- read.dcf(textConnection(str), fields = as.character(1:6))
    x <- replace(x, is.na(x), 0)
    x
    #      1   2   3   4   5   6  
    # [1,] "0" "3" "2" "0" "2" "0"
    # [2,] "5" "4" "0" "0" "0" "3"
    

    要将 data.frame 作为 list numeric 向量返回,请执行以下操作:

    mydf$v3_l <- lapply(1:nrow(x), function(y) as.numeric(x[y, ]))
    

    这是结果 str

    str(mydf)
    'data.frame':   2 obs. of  3 variables:
     $ v2  : num  1 2.01
     $ v3  : chr  "2:3,3:2,5:2," "1:5,2:4,6:3,"
     $ v3_l:List of 2
      ..$ : num  0 3 2 0 2 0
      ..$ : num  5 4 0 0 0 3
    
  • 4

    这是另一种仅使用 base 函数的方法 .

    首先,字符串被 :, 拆分( strsplit ) . 奇数位置处的元素对应于索引,甚至位置对应于值 . 我们预先分配了 max max 索引的 numeric 向量 .

    lapply 循环中,我们将分裂矢量(即偶数元素; x[c(FALSE, TRUE)] )的值分配给索引处的预分配矢量 vec (即分裂矢量的奇数元素; x[c(TRUE, FALSE)] ) .

    l <- strsplit(df$v3, "[:|,]")
    vec <- numeric(length = max(as.integer(unlist(l)[c(TRUE, FALSE)])))
    
    df$v3 <- lapply(l, function(x){
      x <- as.numeric(x)
      vec[x[c(TRUE, FALSE)]] <- x[c(FALSE, TRUE)]
      vec
      })
    
    df
    #      v2               v3
    # 1 1.000 0, 3, 2, 0, 2, 0
    # 2 2.012 5, 4, 0, 0, 0, 3
    

相关问题