#r #split #dataframe
#r #сплит #фрейм данных
Вопрос:
Я хочу разделить персонажей. Хотя у меня есть большой фрейм данных для работы, следующий небольшой пример покажет, что нужно сделать.
mydf <- data.frame (name = c("L1", "L2", "L3"),
M1 = c("AC", "AT", NA), M2 = c("CC", "--", "TC"), M3 = c("AT", "TT", "AG"))
Я хочу разделить символы для переменных M1 на M3 (в реальном наборе данных у меня > 6000 переменных)
name M1a M1b M2a M2b M3a M3b
L1 A C C C A T
L2 A T - - T T
L3 NA NA T C A G
Я попробовал следующие коды:
func<- function(x) {sapply( strsplit(x, ""),
match, table= c("A","C","T","G", "--", NA))}
odataframe <- data.frame(apply(mydf, 1, func) )
colnames(odataframe) <- paste(rep(names(mydf), each = 2), c("a", "b"), sep = "")
odataframe
Ответ №1:
Вот так:
splitCol <- function(x){
x <- as.character(x)
x[is.na(x)] <- "$"
z <- matrix(unlist(strsplit(x, split="")), ncol=2, byrow=TRUE)
z[z=="$"] <- NA
z
}
newdf <- as.data.frame(do.call(cbind, lapply(mydf[, -1], splitCol)))
names(newdf) <- paste(rep(names(mydf[, -1]), each=2), c("a", "b"), sep="")
newdf <- data.frame(mydf[, 1, drop=FALSE], newdf)
newdf
name M1a M1b M2a M2b M3a M3b
1 L1 A C C C A T
2 L2 A T - - T T
3 L3 <NA> <NA T C A G
Комментарии:
1. спасибо за быстрый ответ, приятно, но все же кажется, что есть проблема, связанная с обработкой NA в M1a и M1b, в третьей строке должны быть NA и NA (не NA и A)
2. Я исправил это за несколько секунд до вашего комментария. Попробуйте еще раз.
3. Это может быть очень применимо ко мне. Спасибо за публикацию. Я объединил его в функцию и решил поделиться. Спасибо за сообщение.
Ответ №2:
Код Андри как воспроизводимая функция
splitCol <- function(dataframe, splitVars=names(dataframe)){
split.DF <- dataframe[,splitVars]
keep.DF <- dataframe[, !names(dataframe) %in% c(splitVars)]
X <- function(x)matrix(unlist(strsplit(as.character(x), split="")), ncol=2, byrow=TRUE)
newdf <- as.data.frame(do.call(cbind, suppressWarnings(lapply(split.DF, X))) )
names(newdf) <- paste(rep(names(split.DF), each=2), c(".a", ".b"), sep="")
data.frame(keep.DF,newdf)
}
Проверьте это
splitCol(mydf)
splitCol(mydf, c('M1','M2'))
Пожалуйста, не голосуйте за это как за правильный ответ. Ответ Андри явно является первым правильным ответом. Это просто расширение его кода для большего количества ситуаций. Спасибо за вопрос и спасибо за код, Андри.