brandonps
brandonps

Reputation: 15

How can I sum vectors nested in a column of a data frame?

I have a data frame where one column contains a list. I want to convert the list to numeric and sum the values into a new column. Each row has a column with a vector like this:

c("47", "39", "1")

The new column would contain the sum of those numbers and would look like this:

List                  SumList
c("47", "39", "1")     87
c("11", "11")          22
c("1", "2")             3

I have tried a couple different approaches, but nothing seems to produce the outcome I need.

Example data frame:

DF <- structure(list(list = structure(list(c("47", "39", "1"), c("11", 
"11"), c("1", "2")))), class = "data.frame", row.names = c(NA, -3L))

Upvotes: 1

Views: 791

Answers (4)

G. Grothendieck
G. Grothendieck

Reputation: 269852

1) Assuming the data frame in the Note at the end, try the following code. No packages are used.

transform(DF, sum = sapply(list, function(x) sum(as.numeric(x))))

giving:

       list sum
1 47, 39, 1  87
2    11, 11  22
3      1, 2   3

2) Another approach is to convert DF to a long form and then sum that giving the same result. Again no packages are used.

long <- stack(setNames(DF$list, seq_along(DF$list)))
transform(DF, sum = rowsum(as.numeric(long$value), long$ind))

Note

The input in reproducible form:

DF <- structure(list(list = structure(list(c("47", "39", "1"), c("11", 
"11"), c("1", "2")))), class = "data.frame", row.names = c(NA, -3L))

Upvotes: 3

LocoGris
LocoGris

Reputation: 4480

Supposing we use G. Grothendieck structure:

DF <- structure(list(list = structure(list(c("47", "39", "1"), c("11", 
                                                                 "11"), c("1", "2")))), class = "data.frame", row.names = c(NA, -3L))

DF$SumList <-lapply(1:nrow(DF), function(x) sum(as.double(unlist(DF$list[x]))))

And with Frank input:

DF$SumList <-lapply(1:nrow(DF), function(x) sum(as.double(DF$list[[x]])))

Upvotes: 0

Dan
Dan

Reputation: 12084

Here's a purrr solution that uses map_dbl.

library(dplyr)
library(tibble)
library(purrr)

tibble(x = list(c("47", "39", "1"), c("11","11"), c("1","2"))) %>% 
  mutate(Sum = map_dbl(x, function(i)sum(as.numeric(i))))
#> # A tibble: 3 x 2
#>   x           Sum
#>   <list>    <dbl>
#> 1 <chr [3]>    87
#> 2 <chr [2]>    22
#> 3 <chr [2]>     3

Created on 2019-03-20 by the reprex package (v0.2.1)

Upvotes: 2

Dave Rosenman
Dave Rosenman

Reputation: 1467

You can accomplish what you want using the dplyr functions rowwise and mutate.

Example:

library(dplyr)
df <- tibble(List = list(c("47", "39", "1"), c("11","11"), c("1","2"))) %>% 
  rowwise() %>% 
  mutate(SumList = sum(as.numeric(List)))

Upvotes: 4

Related Questions