Reputation: 61
I have a vector that looks like :
numbers <- c("1/1/1", "1/0/2", "1/1/1/1", "2/0/1/1", "1/2/1")
(not always the same number of "/" character)
How can I create another vector with the sum of the numbers of each string?
Something like :
sum
3
3
4
4
4
Upvotes: 6
Views: 4707
Reputation: 269654
1) strapply strapply
matches each string of digits using \\d+
and then applies as.numeric
to it returning a list with one vector of numbers per input string. We then apply sum
to each of those vectors. This solution seems particularly short.
library(gsubfn)
sapply(strapply(numbers, "\\d+", as.numeric), sum)
## [1] 3 3 4 4 4
2) read.table This applies sum(read.table(...))
to each string. It is a bit longer (but still only one line of code) but uses no packages.
sapply(numbers, function(x) sum(read.table(text = x, sep = "/")))
## 1/1/1 1/0/2 1/1/1/1 2/0/1/1 1/2/1
## 3 3 4 4 4
Add the USE.NAMES = FALSE
argument to sapply
if you don't want names on the output.
scan(textConnection(x), sep = "/", quiet = TRUE)
could be used in place of read.table
but is longer.
Upvotes: 0
Reputation: 521289
What seems to me to be the most straightforward approach here is to convert your number strings to actual valid string arithmetic expressions, and then evaluate them in R using eval
along with parse
. Hence, the string 1/0/2
would become 1+0+2
, and then we can simply evaluate that expression.
sapply(numbers, function(x) { eval(parse(text=gsub("/", "+", x))) })
1/1/1 1/0/2 1/1/1/1 2/0/1/1 1/2/1
3 3 4 4 4
Upvotes: 3
Reputation: 37879
One solution with strsplit
and sapply
:
sapply(strsplit(numbers, '/'), function(x) sum(as.numeric(x)))
#[1] 3 3 4 4 4
strsplit
will split your stings on /
(doesn't matter how many /
s you have). The output of strsplit
is a list, so we iterate over it to calculate the sum with sapply
.
Upvotes: 5