通过字符的第n个实例在数据框中拆分列

时间:2018-11-28 20:12:31

标签: r dataframe split dplyr character

我有一个包含几列的数据框,这些列之一由管道“ |”填充和我要获取的信息。

例如:

View(Table$Column)
"|1||KK|12|Gold||4K|"
"|1||Rst|E|Silver||13||"
"|1||RST|E|Silver||18||"
"|1||KK|Y|Iron|y|12||"
"|1||||Copper|Cpr|||E"
"|1||||Iron|||12|F"

以此类推,大约有12万行。 我要挖掘的是本系列中第5个管道和第6个管道之间的所有东西,但是由于它是自己的列向量,因此最终结果看起来像这样:

View(Extracted)
Gold
Silver
Silver
Iron
Copper
Iron

我不想使用RegEx。我的工具仅限于R。你们碰巧对如何克服这个问题有任何建议吗?

谢谢。

3 个答案:

答案 0 :(得分:3)

1)假定x在最后的注释中可重复定义,请使用read.table,如图所示。不使用正则表达式或包。

read.table(text = Table$Column, sep = "|", header = FALSE, 
  as.is = TRUE, fill = TRUE)[6]

给予:

      V6
1   Gold
2 Silver
3 Silver
4   Iron
5 Copper
6   Iron

2)此替代方法确实使用了正则表达式(问题不要求使用正则表达式),但以防万一,这是一个tidyr解决方案。请注意,它需要tidyr 0.8.2或更高版本,因为早期版本的tidyr不支持NA参数中的into=

library(dplyr)
library(tidyr)

Table %>% 
  separate(Column, into = c(rep(NA, 5), "commodity"), sep = "\\|", extra = "drop")

给予:

  commodity
1      Gold
2    Silver
3    Silver
4      Iron
5    Copper
6      Iron

3)这是另一个基本解决方案。考虑到(1)这么简单,可能不是您想要的那种,但是我想看看我们是否可以在不使用正则表达式的基础上提出第二种方法。请注意,如果split=的{​​{1}}自变量为strsplit,则将对其进行特殊处理,而不是正则表达式。它创建一个列表,每个列表的组成部分都是单个字符的向量。每个这样的向量都传递给匿名函数,该函数用序号标记""及其后的字段中的字符。然后,我们取对应于5的字符(第一个字符除外,因为它是|),并使用|将它们折叠在一起。

paste

给予:

data.frame(commodities = sapply(strsplit(Table$Column, ""), function(chars) {
  wx <- which(cumsum(chars == "|") == 5)
  paste(chars[seq(wx[2], tail(wx, 1))], collapse = "")
}), stringsAsFactors = FALSE)

注意

  commodities
1        Gold
2      Silver
3      Silver
4        Iron
5      Copper
6        Iron

答案 1 :(得分:2)

您可以尝试以下方法:

df <- data.frame(x = c("|1||KK|12|Gold||4K|", "|1||Rst|E|Silver||13||"), stringsAsFactors = FALSE)
library(stringr)
stringr::str_split(df$x, "\\|", simplify = TRUE)[, 6]

答案 2 :(得分:1)

1)我们可以在定界符strsplit上使用base R中的|,并从{{1 }} s

list

2)或使用vector(同样来自sapply(strsplit(Table$Column, "|", fixed = TRUE), `[`, 6) #[1] "Gold" "Silver" "Silver" "Iron" "Copper" "Iron" ),使用regex提取第6个字

base R

数据

sub