5 votos

División de una columna numérica para un marco de datos

Tengo un dataframe df como se muestra a continuación

  name  position            
1 HLA   1:1-15            
2 HLA   1:2-16 
3 HLA   1:3-17         

Me gustaría dividir la columna de posición en dos columnas más basadas en el carácter ":" de forma que obtenga

name    seq    position            
1 HLA   1       1-15            
2 HLA   1       2-16 
3 HLA   1       3-17 

Así que pensé que esto serviría,

df <- transform(df,pos = as.character(position)) 

df_split<- strsplit(df$pos, split=":")

#found this hack from an old mailing list post
df <- transform(df, seq_name= sapply(df_split, "[[", 1),pos2= sapply(df_split, "[[", 2))

sin embargo obtengo un error

Error in strsplit(df$pos, split = ":") : non-character argument

¿Qué puede fallar? Cómo se consigue esto en R. He simplificado mi caso aquí, en realidad el marco de datos tiene más de cien mil filas.

1 votos

Tal vez estoy haciendo algo mal, pero su I no obtener ningún error si df$pos es un vector de caracteres. ¿Puede usted pls dput ¿tu data.frame?

1 votos

@suncoolsu : La llamada de transformación utiliza la convención as.data.frame de stringsAsFactors=TRUE por lo que el objetivo de obtener una columna de caracteres fue derrotado. Era otra columna de factores. Mejor hubiera sido utilizar as.character alrededor del argumento pasado a strsplit. Código completo a continuación.

10voto

aron Puntos 174
df_split<- strsplit(as.character(df$position), split=":")
df <- transform(df, seq_name= sapply(df_split, "[[", 1),pos2= sapply(df_split, "[[", 2))
> 
> df
  name position    pos seq_name pos2
1  HLA   1:1-15 1:1-15        1 1-15
2  HLA   1:2-16 1:2-16        1 2-16
3  HLA   1:3-17 1:3-17        1 3-17

2 votos

+1, no sabía que se podía pasar [[ como una función.

0 votos

@mpiktas: Sí, y también se puede pasar "[" como función, incluso a veces añadiendo una coma extra con un argumento vacío seguido de una segunda expresión de índice para trabajar sobre columnas en dataframes o para llegar a partes de otras listas. Probablemente "[<-" también, pero no tengo un ejemplo preparado en mente, y no sé si podría haber algún tipo de problema de entorno.

3voto

Hassan Usman Puntos 29

Aquí hay un método de una línea usando tidyr.separate():

library(tidyr)
df <- separate(df, position, into = c("seq","position"), sep = ":", extra = "merge")

2voto

Brett Veenstra Puntos 10238

El "truco" consiste en utilizar do.call .

> a <- data.frame(x = c("1:1-15", "1:2-16", "1:3-17"))
> a
       x
1 1:1-15
2 1:2-16
3 1:3-17
> a$x <- as.character(a$x)
> a.split <- strsplit(a$x, split = ":")
> tmp <-do.call(rbind, a.split)
> data.frame(a, tmp)
       x X1   X2
1 1:1-15  1 1-15
2 1:2-16  1 2-16
3 1:3-17  1 3-17

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X