tributarios - Estilo de diccionario reemplazar varios elementos
terminos tributarios en ingles (8)
Aquí hay algo simple que hará el trabajo:
key <- c(''AA'',''AC'',''AG'')
val <- c(''0101'',''0102'',''0103'')
lapply(1:3,FUN = function(i){foo[foo == key[i]] <<- val[i]})
foo
snp1 snp2 snp3
1 0101 0101 <NA>
2 0103 AT GG
3 0101 0103 GG
4 0101 0101 GC
lapply
emitirá una lista en este caso que realmente no nos importa. Puede asignar el resultado a algo si lo desea y luego descartarlo. Aquí estoy iterando sobre los índices, pero usted mismo podría ubicar las claves / valores en una lista y repetirlos directamente. Tenga en cuenta el uso de la asignación global con <<-
.
Hice mapply
con una forma de hacer esto con mapply
pero mi primer intento no funcionó, así que cambié. mapply
embargo, sospecho que una solución con mapply
es posible.
Tengo una gran cantidad de datos. Marco de datos de caracteres que deseo convertir según lo que comúnmente se denomina diccionario en otros idiomas.
Actualmente lo estoy haciendo así:
foo <- data.frame(snp1 = c("AA", "AG", "AA", "AA"), snp2 = c("AA", "AT", "AG", "AA"), snp3 = c(NA, "GG", "GG", "GC"), stringsAsFactors=FALSE)
foo <- replace(foo, foo == "AA", "0101")
foo <- replace(foo, foo == "AC", "0102")
foo <- replace(foo, foo == "AG", "0103")
Esto funciona bien, pero obviamente no es bonito y parece tonto repetir la declaración de replace
cada vez que deseo reemplazar un elemento en el data.frame.
¿Hay una forma mejor de hacerlo ya que tengo un diccionario de aproximadamente 25 pares clave / valor?
Aquí hay una solución rápida.
dict = list(AA = ''0101'', AC = ''0102'', AG = ''0103'')
foo2 = foo
for (i in 1:3){foo2 <- replace(foo2, foo2 == names(dict[i]), dict[i])}
Como han pasado algunos años desde la última respuesta, y esta noche surgió una nueva pregunta sobre este tema y un moderador la cerró, la agregaré aquí. El póster tiene un marco de datos grande que contiene 0, 1 y 2, y desea cambiarlos a AA, AB y BB respectivamente.
Utilice plyr
:
> df <- data.frame(matrix(sample(c(NA, c("0","1","2")), 100, replace = TRUE), 10))
> df
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 1 2 <NA> 2 1 2 0 2 0 2
2 0 2 1 1 2 1 1 0 0 1
3 1 0 2 2 1 0 <NA> 0 1 <NA>
4 1 2 <NA> 2 2 2 1 1 0 1
... to 10th row
> df[] <- lapply(df, as.character)
Cree una función sobre el marco de datos usando revalue
para reemplazar varios términos:
> library(plyr)
> apply(df, 2, function(x) {x <- revalue(x, c("0"="AA","1"="AB","2"="BB")); x})
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
[1,] "AB" "BB" NA "BB" "AB" "BB" "AA" "BB" "AA" "BB"
[2,] "AA" "BB" "AB" "AB" "BB" "AB" "AB" "AA" "AA" "AB"
[3,] "AB" "AA" "BB" "BB" "AB" "AA" NA "AA" "AB" NA
[4,] "AB" "BB" NA "BB" "BB" "BB" "AB" "AB" "AA" "AB"
... and so on
Si está abierto a usar paquetes, plyr
es muy popular y tiene esta práctica función de mapvalues() que hará lo que está buscando:
foo <- mapvalues(foo, from=c("AA", "AC", "AG"), to=c("0101", "0102", "0103"))
Tenga en cuenta que funciona para tipos de datos de todo tipo, no solo de cadenas.
Usé la respuesta de @ Ramnath anterior, pero la hice leer (qué reemplazar y con qué reemplazar) de un archivo y usar gsub en lugar de reemplazar.
hrw <- read.csv("hgWords.txt", header=T, stringsAsFactor=FALSE, encoding="UTF-8", sep="/t")
for (i in nrow(hrw))
{
document <- gsub(hrw$from[i], hrw$to[i], document, ignore.case=TRUE)
}
hgword.txt contiene la siguiente pestaña separada
"from" "to"
"AA" "0101"
"AC" "0102"
"AG" "0103"
Usando dplyr :: recode :
library(dplyr)
mutate_all(foo, funs(recode(., "AA" = "0101", "AC" = "0102", "AG" = "0103",
.default = NA_character_)))
# snp1 snp2 snp3
# 1 0101 0101 <NA>
# 2 0103 <NA> <NA>
# 3 0101 0103 <NA>
# 4 0101 0101 <NA>
Tenga en cuenta que esta respuesta comenzó como un intento de resolver el problema mucho más simple publicado en ¿Cómo reemplazar todos los valores en el marco de datos con un vector de valores? . Desafortunadamente, esta pregunta se cerró como duplicado de la pregunta real. Por lo tanto, intentaré sugerir una solución basada en la sustitución de los niveles de factor para ambos casos, aquí.
En caso de que solo haya un vector (o una columna de marco de datos) cuyos valores deban reemplazarse y no haya objeciones para usar el factor, podemos forzar al vector a factorizar y cambiar los niveles de factor según sea necesario:
x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
x <- factor(x)
x
#[1] 1 1 4 4 5 5 1 1 2
#Levels: 1 2 4 5
replacement_vec <- c("A", "T", "C", "G")
levels(x) <- replacement_vec
x
#[1] A A C C G G A A T
#Levels: A T C G
Usando el paquete forcats
, esto se puede hacer en una sola línea:
x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
forcats::lvls_revalue(factor(x), replacement_vec)
#[1] A A C C G G A A T
#Levels: A T C G
En caso de que todos los valores de varias columnas de un marco de datos deban ser reemplazados, el enfoque puede extenderse.
foo <- data.frame(snp1 = c("AA", "AG", "AA", "AA"),
snp2 = c("AA", "AT", "AG", "AA"),
snp3 = c(NA, "GG", "GG", "GC"),
stringsAsFactors=FALSE)
level_vec <- c("AA", "AC", "AG", "AT", "GC", "GG")
replacement_vec <- c("0101", "0102", "0103", "0104", "0302", "0303")
foo[] <- lapply(foo, function(x) forcats::lvls_revalue(factor(x, levels = level_vec),
replacement_vec))
foo
# snp1 snp2 snp3
#1 0101 0101 <NA>
#2 0103 0104 0303
#3 0101 0103 0303
#4 0101 0101 0302
Tenga en cuenta que level_vec
y replacement_vec
deben tener longitudes iguales.
Más importante aún, level_vec
debe estar completo , es decir, incluir todos los valores posibles en las columnas afectadas del marco de datos original. (Utilice unique(sort(unlist(foo)))
para verificar). De lo contrario, cualquier valor faltante será obligado a <NA>
. Tenga en cuenta que esto también es un requisito para la respuesta de Martin Morgan .
Por lo tanto, si solo hay que reemplazar algunos valores, probablemente estará mejor con una de las otras respuestas, por ejemplo, la de Ramnath''s .
map = setNames(c("0101", "0102", "0103"), c("AA", "AC", "AG"))
foo[] <- map[unlist(foo)]
asumiendo que el map
cubre todos los casos en foo
. Esto se sentiría menos como un ''hack'' y sería más eficiente tanto en espacio como en tiempo si foo
fuera una matriz (de carácter ()), entonces
matrix(map[foo], nrow=nrow(foo), dimnames=dimnames(foo))
Tanto la matriz como las variantes de trama de datos son contrarias al límite de 2 ^ 31-1 de R en el tamaño del vector cuando hay millones de SNP y miles de muestras.