将键值对转换为数据帧

时间:2015-08-12 04:48:25

标签: r key-value

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

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

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

Length                    width        height    
 32                         20       
 40                         30          10 

提前致谢

2 个答案:

答案 0 :(得分:1)

您可以使用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

答案 1 :(得分:0)

使用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”。使用deve版本的'data.table'中的tstrsplit,即v1.9.5,我们会在:分割。根据分组变量'V1'创建序列列('indx'),删除'NA'行并使用dcast中的data.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))