Tengo una cadena que tiene el valor que se indica a continuación, separada por una barra vertical.

String1 <- "5|10|25|25|10|10|10|5"
String2 <- "5|10|25|25"

¿Hay alguna función directa para obtener la suma de los números en una cadena? En este caso, debería ser 100 para Srting1 y 65 para string2, y tengo un vector de caracteres de ese tipo.

>chk
                chk
1 5|10|25|25|10|10|10|5
2       5|55|20|5|5|5|5
3                     6
4        Not Available
> sum(scan(text=gsub("\\Not Available\\b", "NA", chk$chk), sep="|", what = numeric(), quiet=TRUE), na.rm = TRUE)
[1] 206

Como debería ser

 [1]100 100 6 NA
2
Shivpe_R 15 dic. 2016 a las 08:40

2 respuestas

La mejor respuesta

Podemos hacer un scan y luego sum

sum(scan(text=String1, sep="|", what = numeric(), quiet=TRUE))

Para varios vectores, colóquelo en un list y haga la misma operación

sapply(mget(paste0("String", 1:2)), function(x) 
        sum(scan(text=x, sep="|", what=numeric(), quiet=TRUE)))
# String1 String2 
#    100      65 

Otra opción es eval(parse( (aunque no se recomienda) después de reemplazar | con +

eval(parse(text=gsub("[|]", "+", String1)))
#[1] 100

O como @thelatemail mencionó en los comentarios, asigne (<-) el | a + y luego haga el eval(parse( ..

`|` <- `+`
eval(parse(text=String1))
#[1] 100

Si tenemos una columna data.frame con cadenas, entonces puede ser mejor dividir por | a un list de vector s, convertir los vector s a numeric (todos los elementos no numéricos obligan a NA con una advertencia amistosa), obtén el sum con na.rm=TRUE

sapply(strsplit(as.character(chk$chk), "[|]"), 
     function(x) sum(as.numeric(x), na.rm=TRUE))
#[1] 100 100   6   0

NOTA: El as.character no es necesario si la columna 'chk' ya es una clase character

De lo contrario, si estamos usando scan o eval(parse, debería hacerse para cada elemento.

4
akrun 15 dic. 2016 a las 07:11

Podemos extraer todos los números de la cadena y luego sum sobre ella

library(stringr)
sum(as.numeric(unlist(str_match_all(String1, "[0-9]+"))))
#[1] 100

sum(as.numeric(unlist(str_match_all(String2, "[0-9]+"))))
#[1] 65

Para múltiples vectores, podemos mantenerlo en una lista.

sapply(list(String1, String2), function(x) 
                                  sum(as.numeric(unlist(str_match_all(x, "[0-9]+")))))
#[1] 100  65
2
Ronak Shah 15 dic. 2016 a las 05:51