R 按字符的第n个实例拆分数据帧中的列

R 按字符的第n个实例拆分数据帧中的列,r,dataframe,split,dplyr,character,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(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
我不想用正则表达式。我的工具在这里仅限于R。你们有什么建议来克服这个问题吗

谢谢。

1)我们可以在分隔符
上使用
基R
中的
strsplit
,并从
向量的
列表中提取第6个元素

sapply(strsplit(Table$Column, "|", fixed = TRUE), `[`, 6)
#[1] "Gold"   "Silver" "Silver" "Iron"   "Copper" "Iron"

2)或使用
regex
(再次从
base R
),使用
sub
提取第6个单词

sub("^([|][^|]+){4}[|]([^|]*).*", "\\2", 
       gsub("(?<=[|])(?=[|])", "and", Table$Column, perl = TRUE))
#[1] "Gold"   "Silver" "Silver" "Iron"   "Copper" "Iron"  
sub(“^([|][^ |]+){4}[|]([^ |]*)*)*,“\\2”,
gsub((?1)我们可以在分隔符
上使用
strsplit
中的
基R
,并从
向量的
列表中提取第6个元素

sapply(strsplit(Table$Column, "|", fixed = TRUE), `[`, 6)
#[1] "Gold"   "Silver" "Silver" "Iron"   "Copper" "Iron"

2)或使用
regex
(再次从
base R
),使用
sub
提取第6个单词

sub("^([|][^|]+){4}[|]([^|]*).*", "\\2", 
       gsub("(?<=[|])(?=[|])", "and", Table$Column, perl = TRUE))
#[1] "Gold"   "Silver" "Silver" "Iron"   "Copper" "Iron"  
sub(“^([|][^ |]+){4}[|]([^ |]*)*)*,“\\2”,
gsub((?您可以尝试以下方法:

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]
df您可以尝试以下方法:

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]
df1)假设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
  commodity
1      Gold
2    Silver
3    Silver
4      Iron
5    Copper
6      Iron
  commodities
1        Gold
2      Silver
3      Silver
4        Iron
5      Copper
6        Iron
2)此替代方案确实使用了正则表达式(问题不要求使用正则表达式),但为了以防万一,这里是一个tidyr解决方案。请注意,它需要tidyr 0.8.2或更高版本,因为早期版本的tidyr在
into=
参数中不支持
NA

library(dplyr)
library(tidyr)

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

      V6
1   Gold
2 Silver
3 Silver
4   Iron
5 Copper
6   Iron
  commodity
1      Gold
2    Silver
3    Silver
4      Iron
5    Copper
6      Iron
  commodities
1        Gold
2      Silver
3      Silver
4        Iron
5      Copper
6        Iron
3)这是另一个基本解决方案。鉴于(1)要简单得多,这可能不是您想要的解决方案,但我想看看是否可以在base中找到第二种不使用正则表达式的方法。请注意,如果
strsplit
split=
参数是
然后它被特殊处理,因此不是正则表达式。它创建了一个列表,其中每个组件都是单个字符的向量。每个这样的向量都被传递给匿名函数,该函数用序号标记
|
和它后面字段中的字符。然后我们获取对应于5的字符(第一个除外,因为它是
|
)并使用
粘贴将它们折叠在一起

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)
1)假设x在最终用途注释中重复定义
读取。表
如图所示。不使用正则表达式或包

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
  commodity
1      Gold
2    Silver
3    Silver
4      Iron
5    Copper
6      Iron
  commodities
1        Gold
2      Silver
3      Silver
4        Iron
5      Copper
6        Iron
2)这个替代方案确实使用了正则表达式(问题不要求使用正则表达式),但为了以防万一,这里有一个tidyr解决方案。请注意,它需要tidyr 0.8.2或更高版本,因为早期版本的tidyr在
into=
参数中不支持
NA

library(dplyr)
library(tidyr)

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

      V6
1   Gold
2 Silver
3 Silver
4   Iron
5 Copper
6   Iron
  commodity
1      Gold
2    Silver
3    Silver
4      Iron
5    Copper
6      Iron
  commodities
1        Gold
2      Silver
3      Silver
4        Iron
5      Copper
6        Iron
3)这是另一种基本解决方案。这可能不是你想要的方法,因为(1)要简单得多,但我想看看我们是否能在base中找到第二种不使用regex的方法。请注意,如果
strsplit
split=
参数是
,那么它将被特殊处理,因此不是正则表达式。它创建一个列表,其中每个组件都是单个字符的向量。每个这样的向量都传递给匿名函数,该函数用序号标记
|
及其后面字段中的字符。然后,我们获取对应于5的字符(第一个字符除外,因为它是
|
),并使用
粘贴将它们折叠在一起

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)
表格