R如何创建多个包含子字符串字符的变量
R How to create several variables containing substring characters
我的数据文件包含一个变量,其中包含对几个问题的回答。
结构是:
ID response
1 BCCAD
2 ABCCD
3 BA.DC
.....
我想在新变量 q1、q2、.. 中分隔每个响应:
ID q1 q2 q3 q4 q5
1 B C C A D
2 A B C C D
3 B A . D C
....
我尝试了以下代码
v <- rep("q",5)
z <- as.character(1:5)
paste(v,z,sep="")
for(i in 1:20){
f[i]<- substr(response,i,i)
}
但它只是替换向量中的变量名。
我打算根据需要创建尽可能多的变量来存储每个问题的值。变量应使用公共根 "q" 和显示字符串中位置的下标命名。
这里有一个方法:
df=data.frame(ID=1:3,response=c("BCCAD","ABCCD","BA.DC"))
response.split <- as.data.frame(do.call("rbind",lapply(split(df$response,df$ID),FUN=function(vec){strsplit(as.character(vec),"")[[1]]})))
names(response.split) <- paste("q",1:ncol(response.split),sep="")
out <- cbind(ID=df$ID,response.split)
out
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
您可以使用strsplit
函数:
DF <-
read.csv(text="ID,response
1,BCCAD
2,ABCCD
3,BA.DC",header=TRUE)
DF2 <- cbind(DF['ID'], do.call(rbind,strsplit(as.character(DF$response),"")))
names(DF2)[-1] <- paste0('q',1:(ncol(DF2)-1))
> DF2
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
请注意,只有当响应列中的所有字符串都具有相同数量的字符时,这才有效。
其他几个选项:
1) tidyr
包中的 separate
函数:
library(tidyr)
# notation 1:
separate(d, col=response, into=paste0('q',1:5), sep=1:4)
# notation 2:
d %>% separate(col=response, into=paste0('q',1:5), sep=1:4)
2) data.table
包中的 tstrsplit
函数:
library(data.table)
setDT(d)[, paste0('q',1:5) := tstrsplit(response, split = '')][, response := NULL][]
3) splitstackshape
的 cSplit
函数结合 data.table
:
的 setnames
library(splitstackshape)
setnames(cSplit(d, 'response', sep='', stripWhite=FALSE), 2:6, paste0('q',1:5))[]
它们都给出相同的结果:
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
已用数据:
d <- structure(list(ID = 1:3, response = c("BCCAD", "ABCCD", "BA.DC")), .Names = c("ID", "response"), class = "data.frame", row.names = c(NA, -3L))
我的数据文件包含一个变量,其中包含对几个问题的回答。
结构是:
ID response
1 BCCAD
2 ABCCD
3 BA.DC
.....
我想在新变量 q1、q2、.. 中分隔每个响应:
ID q1 q2 q3 q4 q5
1 B C C A D
2 A B C C D
3 B A . D C
....
我尝试了以下代码
v <- rep("q",5)
z <- as.character(1:5)
paste(v,z,sep="")
for(i in 1:20){
f[i]<- substr(response,i,i)
}
但它只是替换向量中的变量名。
我打算根据需要创建尽可能多的变量来存储每个问题的值。变量应使用公共根 "q" 和显示字符串中位置的下标命名。
这里有一个方法:
df=data.frame(ID=1:3,response=c("BCCAD","ABCCD","BA.DC"))
response.split <- as.data.frame(do.call("rbind",lapply(split(df$response,df$ID),FUN=function(vec){strsplit(as.character(vec),"")[[1]]})))
names(response.split) <- paste("q",1:ncol(response.split),sep="")
out <- cbind(ID=df$ID,response.split)
out
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
您可以使用strsplit
函数:
DF <-
read.csv(text="ID,response
1,BCCAD
2,ABCCD
3,BA.DC",header=TRUE)
DF2 <- cbind(DF['ID'], do.call(rbind,strsplit(as.character(DF$response),"")))
names(DF2)[-1] <- paste0('q',1:(ncol(DF2)-1))
> DF2
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
请注意,只有当响应列中的所有字符串都具有相同数量的字符时,这才有效。
其他几个选项:
1) tidyr
包中的 separate
函数:
library(tidyr)
# notation 1:
separate(d, col=response, into=paste0('q',1:5), sep=1:4)
# notation 2:
d %>% separate(col=response, into=paste0('q',1:5), sep=1:4)
2) data.table
包中的 tstrsplit
函数:
library(data.table)
setDT(d)[, paste0('q',1:5) := tstrsplit(response, split = '')][, response := NULL][]
3) splitstackshape
的 cSplit
函数结合 data.table
:
setnames
library(splitstackshape)
setnames(cSplit(d, 'response', sep='', stripWhite=FALSE), 2:6, paste0('q',1:5))[]
它们都给出相同的结果:
ID q1 q2 q3 q4 q5
1 1 B C C A D
2 2 A B C C D
3 3 B A . D C
已用数据:
d <- structure(list(ID = 1:3, response = c("BCCAD", "ABCCD", "BA.DC")), .Names = c("ID", "response"), class = "data.frame", row.names = c(NA, -3L))