提取在单个列中找到的数据元素

时间:2013-12-06 19:25:12

标签: r data-manipulation

以下是我的数据。

id interest_string
1       YI{Z0{ZI{
2             ZO{
3            <NA>
4             ZT{

如您所见,可以将多个代码连接成一个列,由{分隔。一行也可能没有interest_string值。

如何操作此数据框以将值提取为如下格式:

id  interest
1    YI
1    Z0
1    ZI
2    Z0
3    <NA>
4    ZT

我需要使用R完成此任务。

提前致谢。

2 个答案:

答案 0 :(得分:5)

这是一个解决方案

out <- with(dat, strsplit(as.character(interest_string), "\\{"))
## or
# out <- with(dat, strsplit(as.character(interest_string), "{", fixed = TRUE))

out <- cbind.data.frame(id = rep(dat$id, times = sapply(out, length)),
                        interest = unlist(out, use.names = FALSE))

,并提供:

R> out
  id interest
1  1       YI
2  1       Z0
3  1       ZI
4  2       ZO
5  3     <NA>
6  4       ZT

解释

第一行解决方案只是使用interest_string作为拆分指标,将dat因子的每个元素拆分为数据对象\\{。该指标必须被转义,并且在R中需要两个\(实际上如果您在fixed = TRUE的调用中使用strsplit则不会。)结果对象是一个列表,对于示例数据看起来像这样

R> out
[[1]]
[1] "YI" "Z0" "ZI"

[[2]]
[1] "ZO"

[[3]]
[1] "<NA>"

[[4]]
[1] "ZT"

我们在此列表中几乎拥有所需的所有内容,以形成您需要的输出。我们在此列表中唯一需要的是id值,这些值引用out的每个元素,我们从原始数据中获取这些元素。

因此,在第二行中,我们按列(指定数据帧方法,因此我们得到一个返回的数据帧)绑定原始id值,每个值重复所需的次数,到strsplit列表(out)。通过取消列出该列表,我们将其展开到一个向量,该向量具有您预期输出所需的长度。我们需要从id返回的列表组件的长度中复制每个strsplit值的次数。

答案 1 :(得分:5)

一个漂亮而整洁的data.table解决方案:

library(data.table)
DT <- data.table( read.table( textConnection("id interest_string
1       YI{Z0{ZI{
2             ZO{
3            <NA>
4             ZT{"), header=TRUE))

DT$interest_string <- as.character(DT$interest_string)

DT[, {
  list(interest=unlist(strsplit( interest_string, "{", fixed=TRUE )))
}, by=id]

给了我

   id interest
1:  1       YI
2:  1       Z0
3:  1       ZI
4:  2       ZO
5:  3     <NA>
6:  4       ZT