R - 将数据框单元格中的数字加在一起

R - Adding numbers within a data frame cell together

我有一个数据框,其中的值存储为字符。但是,许多值包含两个需要相加的数字。示例:

                    2014 Q1 Sales   2014 Q2 Sales   2014 Q3 Sales   2014 Q4 Sales 
  Product 1                  3+6            2+10               8            13+2
  Product 2                    6             4+0            <NA>               5
  Product 3                 <NA>             5+9             3+1              11

有没有一种方法可以遍历整个数据框并将包含“3+6”等字符的所有单元格替换为等于它们总和的新值?我假设这将涉及将字符强制转换为数字或整数,但我不知道对于其中带有 + 符号的值如何实现。我希望示例数据框最终看起来像这样:

                    2014 Q1 Sales   2014 Q2 Sales   2014 Q3 Sales   2014 Q4 Sales 
  Product 1                    9              12               8              15
  Product 2                    6               4            <NA>               5
  Product 3                 <NA>              14               4              11

这是一个更简单的例子:

dat <- data.frame(a=c("3+6", "10"), b=c("12", NA), c=c("3+4", "5+6"))
dat
##      a    b   c
##  1 3+6   12 3+4
##  2  10 <NA> 5+6

apply(dat, 1:2, function(x) eval(parse(text=x)))
##       a  b  c
## [1,]  9 12  7
## [2,] 10 NA 11

使用 R 本身与 evalparse 进行计算。

这是一个选项 gsubfn,但不使用 eval(parse。我们将 'data.frame' 转换为 'matrix' (as.matrix(dat))。我们匹配数字 ([0-9]+),使用括号 ((..)) 将其捕获为一组,然后是 +,然后是第二组数字,并通过转换为 [=19 来替换它=] class 然后执行 +。可以将输出分配回原始数据集以获得与 'dat'.

中相同的结构
library(gsubfn)
dat[] <- as.numeric(gsubfn('([0-9]+)\+([0-9]+)', 
                  ~as.numeric(x)+as.numeric(y), as.matrix(dat)))

dat
#          2014 Q1 Sales 2014 Q2 Sales 2014 Q3 Sales 2014 Q4 Sales
#Product 1             9            12             8            15
#Product 2             6             4            NA             5
#Product 3            NA            14             4            11

或者我们可以用 lapply 循环列,然后用 gsubfn 对每一列进行替换。

 dat[] <- lapply(dat, function(x) as.numeric(gsubfn('([0-9]+)\+([0-9]+)', 
        ~as.numeric(x)+as.numeric(y),  as.character(x))))

数据

dat <- structure(list(`2014 Q1 Sales` = structure(c(1L, 2L, NA), .Label = c("3+6", 
"6"), class = "factor"), `2014 Q2 Sales` = structure(1:3, .Label = c("2+10", 
"4+0", "5+9"), class = "factor"), `2014 Q3 Sales` = structure(c(2L, 
NA, 1L), .Label = c("3+1", "8"), class = "factor"), `2014 Q4 Sales` = structure(c(2L, 
3L, 1L), .Label = c("11", "13+2", "5"), class = "factor")), .Names = c("2014 Q1 Sales", 
"2014 Q2 Sales", "2014 Q3 Sales", "2014 Q4 Sales"), class = "data.frame", row.names = c("Product 1", 
"Product 2", "Product 3"))