Как я могу разбить символьную строку в кадре данных на несколько столбцов
Я работаю с фреймом данных, один столбец которого содержит значения, которые в основном являются числовыми, но могут содержать нечисловые записи. Я хотел бы разбить этот столбец на несколько столбцов. Один из новых столбцов должен содержать числовую часть исходной записи, а другой столбец должен содержать любые нечисловые элементы.
Вот пример фрейма данных:
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
Особенностью данных, которыми я в настоящее время пользуюсь, является то, что структура строк символов всегда следующая: нечисловые элементы (если они существуют) всегда предшествуют числовым элементам, и эти два элемента всегда разделяются пробелом.
Я могу использовать 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
но это кажется громоздким.
В основном оба варианта, которые я изложил здесь, будут работать. Но я подозреваю, что есть более элегантный или прямой способ получить желаемый фрейм данных.