在R中:拆分字符向量以查找特定字符并返回数据帧

在R中:拆分字符向量以查找特定字符并返回数据帧,r,dataframe,vector,split,strsplit,R,Dataframe,Vector,Split,Strsplit,我希望能够从数据帧中的字符向量中提取特定字符,并返回新的数据帧。我想提取的信息是审计师在特定公司的收入和资产负债表上的评论。我的问题是,审计员的备注存储在包含不同备注的向量中。例如: vec=c(“A c G H D E”)。由于%vec中的“%A”不会返回TRUE,因此我必须使用strsplit分解数据帧中的每个字符向量,因此%unlist中的“%A”(strsplit(dat[I,2])。这将返回TRUE 这里是一个MWE: dat <- data.frame(orgnr = c(1,

我希望能够从数据帧中的字符向量中提取特定字符,并返回新的数据帧。我想提取的信息是审计师在特定公司的收入和资产负债表上的评论。我的问题是,审计员的备注存储在包含不同备注的向量中。例如:

vec=c(“A c G H D E”)
。由于
%vec
中的“%A”不会返回
TRUE
,因此我必须使用
strsplit
分解数据帧中的每个字符向量,因此
%unlist中的“%A”(strsplit(dat[I,2])
。这将返回
TRUE

这里是一个MWE:

dat <- data.frame(orgnr = c(1, 2, 3, 4), rat = as.character(c("A B C")))
dat$rat <- as.character(dat$rat)
dat[2, 2] <- as.character(c("A F H L H"))
dat[3, 2] <- as.character(c("H X L O"))
dat[4, 2] <- as.character(c("X Y Z A B C"))
这将返回以下错误消息:
警告消息:
在(函数(…,deparse.level=1)中:
结果的列数不是向量长度的倍数(arg2)

这是一种理想的方法,因为它速度快,但我不能使用
DF
,因为它可以循环使用。 由于向量的长度不同,有没有办法插入
NA
而不是循环使用?

到目前为止,我已经找到了一个解决问题的方法,将for循环与
ifelse
-语句结合使用。但是,使用300万OB。这种方法需要几年时间

dat$A <- 0

for(i in seq(1, nrow(dat), 1)) {
  print(i)
  dat[i, 3] <- ifelse("A" %in% unlist(strsplit(dat[i, 2], " ")), 1, 0)
}

dat$B <- 0

for(i in seq(1, nrow(dat), 1)) {
  print(i)
  dat[i, 4] <- ifelse("B" %in% unlist(strsplit(dat[i, 2], " ")), 1, 0)
}

我已经搜索了这里关于StackOverflow的大部分相关问题。这个问题与我的问题非常接近:,但我不知道如何用这种方法实现strsplit。

我们可以使用for loop with
grepl
来完成这个任务。
+0
是转换列形式
TRUE
FALSE
到1或0

for (col in c("A", "B")){
  dat[[col]] <- grepl(col, dat$rat) + 0
}
dat
#   orgnr         rat A B
# 1     1       A B C 1 1
# 2     2   A F H L H 1 0
# 3     3     H X L O 0 0
# 4     4 X Y Z A B C 1 1
library(data.table)

# Convert to data.table
setDT(dat)

# Create a helper function
dummy_fun <- function(col, vec){
  grepl(col, vec) + 0
}

# Apply the function to A and B
dat[, c("A", "B") := lapply(c("A", "B"), dummy_fun, vec = rat)] 
dat
#    orgnr         rat A B
# 1:     1       A B C 1 1
# 2:     2   A F H L H 1 0
# 3:     3     H X L O 0 0
# 4:     4 X Y Z A B C 1 1
使用基本R:

a=strsplit(dat$rat," ")
b=data.frame(x=rep(dat$orgnr,lengths(a)),y=unlist(a),z=1)
cbind(dat,as.data.frame.matrix(xtabs(z~x+y,b)))
  orgnr         rat A B C F H L O X Y Z
1     1       A B C 1 1 1 0 0 0 0 0 0 0
2     2   A F H L H 1 0 0 1 2 1 0 0 0 0
3     3     H X L O 0 0 0 0 1 1 1 1 0 0
4     4 X Y Z A B C 1 1 1 0 0 0 0 1 1 1
从这里,您可以调用所需的列:

d=as.data.frame.matrix(xtabs(z~x+y,b))
 cbind(dat,d[c("A","B")])
  orgnr         rat A B
1     1       A B C 1 1
2     2   A F H L H 1 0
3     3     H X L O 0 0
4     4 X Y Z A B C 1 1

感谢您的快速响应,@WWW!当我尝试使用data.table方法运行您的解决方案时,我收到以下警告消息:警告消息:1:In grepl(col,vec):参数“pattern”的长度>1,并且只使用第一个元素,而不使用c(“A”,“B”)我使用一个包含所有不同字母(19个不同字母)的向量。你知道如何克服这个问题吗?(我还收到错误消息,大小太大,“无法分配向量”,但这是意料之中的。我稍后将在功能更强大的计算机上尝试)。不确定您为什么会收到第一条错误消息。如果您使用
lappy
伪函数
逐个应用到每个字符串上,一次应该只有一个模式。不知何故,当我应用存储的字母向量(vec)时,您的方法不起作用。我必须像您在示例中那样输入所有字母。此外,使用数据表方法对超过3个工厂的观察速度非常快。非常感谢!
a=strsplit(dat$rat," ")
b=data.frame(x=rep(dat$orgnr,lengths(a)),y=unlist(a),z=1)
cbind(dat,as.data.frame.matrix(xtabs(z~x+y,b)))
  orgnr         rat A B C F H L O X Y Z
1     1       A B C 1 1 1 0 0 0 0 0 0 0
2     2   A F H L H 1 0 0 1 2 1 0 0 0 0
3     3     H X L O 0 0 0 0 1 1 1 1 0 0
4     4 X Y Z A B C 1 1 1 0 0 0 0 1 1 1
d=as.data.frame.matrix(xtabs(z~x+y,b))
 cbind(dat,d[c("A","B")])
  orgnr         rat A B
1     1       A B C 1 1
2     2   A F H L H 1 0
3     3     H X L O 0 0
4     4 X Y Z A B C 1 1