在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