将键值对转换为数据框

Converting key value pair into a data frame

我现在有以下格式的键值数据

  column1          column2            column3
  length:30         width:20                          
  length:20          height:10         width:10 

现在我想将其转换为以下格式的数据框

Length                    width        height    
 32                         20       
 40                         30          10 

提前致谢

您可以使用 sub

删除文本
setNames(data.frame(lapply(dat, function(x) sub("[a-z]+:", "", x))),
         c("length", "width"))
#   length width
# 1     32    20
# 2     40    30

编辑

对于更新后的问题,

dat <- unlist(dat, use.names = F)              # convert to list
keys <- unique(sub("([a-z]):.*", "\1", dat))  # extract the keys
keys <- keys[keys!=""]                         # remove empty strings like in your example

## Key-values in list
keyvals <- setNames(lapply(keys, function(x) {
    as.numeric(sub("\D+", "", grep(x, dat, fixed=T, value=T)))
}), keys)

## Convert to data.frame
as.data.frame(do.call(cbind, lapply(keyvals, `length<-`, max(lengths(keyvals)))))
#   length width height
# 1     30    20     10
# 2     20    10     NA

使用 dplyr/tidyr 的选项。我们用gather将'wide'格式转换为'long',用filter去掉空行(''),用separate创建两个变量('Val1' 和 'Val2')通过在 : 分隔符处分隔字符串,删除不需要的列 (select(-Var)),按变量之一分组 ('Val1')创建一个序列列 ('indx'),然后从 'long' 转换回 'wide' 格式 (spread).

 library(dplyr)
 library(tidyr)
 gather(df1, Var, Val) %>% 
          filter(Val!='')  %>% 
          separate(Val, c('Val1', 'Val2'), convert=TRUE) %>% 
          select(-Var) %>%
          group_by(Val1) %>% 
          mutate(indx=row_number()) %>%
          spread(Val1, Val2) %>%
          select(-indx) 
 #   height length width
 #1     10     30    20
 #2     NA     20    10

或使用 data.table 的类似方法。我们 unlist 初始数据集,并将其转换为具有单列 (setDT) 的 'data.table'。使用 'data.table' 的开发版本中的 tstrsplit,即 v1.9.5,我们在 : 处拆分。基于分组变量 'V1' 创建序列列 ('indx'),删除 'NA' 行并使用 dcastdata.table 转换回 'long' 到 'wide' 格式。

 library(data.table)#v1.9.5+
 DT <- setDT(list(unlist(df1)))[, tstrsplit(V1, ':', type.convert=TRUE)
      ][, ind:=1:.N, V1][!is.na(V1)]
 dcast(DT, ind~V1, value.var='V2')
 #   ind height length width
 #1:   1     10     30    20
 #2:   2     NA     20    10

数据

df1 <- structure(list(column1 = c("length:30", "length:20"), 
column2 = c("width:20", 
"height:10"), column3 = c("", "width:10")), .Names = c("column1", 
"column2", "column3"), class = "data.frame", row.names = c(NA, -2L))