![](/img/trans.png)
[英]How do I add a character string containing parseable fields into columns that can be added to a dataframe
[英]How can I split a character string in a dataframe into multiple columns
我正在使用数据框,其中一列包含大多数数字但可能包含非数字条目的值。 我想将此列拆分为多列。 其中一个新列应包含原始条目的数字部分,另一列应包含任何非数字元素。
这是一个示例数据框:
df <- data.frame(ID=1:4,x=c('< 0.1','100','A 2.5', '200'))
以下是我希望数据框看起来像:
ID x1 x2
1 < 0.1
2 100
3 A 2.5
4 200
我目前正在利用的数据的特征是字符串的结构总是如下:非数字元素(如果存在)总是在数字元素之前,并且两个元素总是用空格分隔。
我可以使用reshape包中的colsplit来根据空格拆分列。 这个问题是它复制了任何不能分成两个元素的条目,
require(reshape)
df <- transform(df, x=colsplit(x,split=" ", names("x1","x2")))
df
ID x1 x2
1 < 0.1
2 100 100
3 A 2.5
4 200 200
这不是非常有问题,因为我可以进行一些后处理以从列“x1”中删除数字元素。
我也可以在函数内使用strsplit完成我想做的事情:
split.fn <- function(id){
new.val <- unlist(strsplit(as.character(df$x[df$ID==id])," "))
if(length(new.val)==1){
return(data.frame(ID=id,x1="NA",x2=new.val))
}else{
return(data.frame(ID=id,x1=new.val[1],x2=new.val[2]))
}
}
data.frame(rbindlist(lapply(unique(df$ID),split.fn)))
ID x1 x2
1 < 0.1
2 NA 100
3 A 2.5
4 NA 200
但这看起来很麻烦。
基本上我在这里概述的两个选项都可行。 但我怀疑有更优雅或直接的方法来获得所需的数据框架。
你可以使用tidyr的 separate()
tidyr::separate(df, x, c("x1", "x2"), " ", fill = "left")
# ID x1 x2
# 1 1 < 0.1
# 2 2 <NA> 100
# 3 3 A 2.5
# 4 4 <NA> 200
如果您绝对需要删除NA
值,那么您可以这样做
tdy <- tidyr::separate(df, x, c("x1", "x2"), " ", fill = "left")
tdy[is.na(tdy)] <- ""
然后我们有
tdy
# ID x1 x2
# 1 1 < 0.1
# 2 2 100
# 3 3 A 2.5
# 4 4 200
这不使用任何包:
transform(df,
x1 = ifelse(grepl(" ", x), sub(" .*", "", x), NA),
x2 = sub(".* ", "", paste(x)))
赠送:
ID x x1 x2
1 1 < 0.1 < 0.1
2 2 100 <NA> 100
3 3 A 2.5 A 2.5
4 4 200 <NA> 200
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.