首页 > 解决方案 > R - 将存储为字符串的类别相加然后重新转换为字符串的最佳方法?

问题描述

我存储了一些数据,其中包括一个看起来有点像字典的字符串列。一般形式是“类别:数量”的重复元素,例如“A:1,B:3,C:10”等。

在整个表中,它看起来像:

df <- data.frame(
    User = c("Bill", "Fred", "Bill", "John", "Fred"),
    Purchases = c(1, 2, 3, 4, 5),
    Complaints = c(5, 4, 3, 2, 1),
    Data1 = c("A: 1, B: 2, C: 10", "A: 9, B: 10, C: 11", "A: 3, B: 0, C: 0", "A: 5, B: 8, C: 4", "A: 6, B: 6, C: 6"),
    Data2 = c("A: 1, B: 2, C: 3", "A: 1, B: 2, C: 3", "A: 1, B: 2, C: 3", "A: 1, B: 2, C: 3", "A: 1, B: 2, C: 3")
)

我想找到按用户分组的每列的总和,但对于 Data1 和 Data2,总和必须按嵌套类别(A、B 和 C)分组。基于上述示例表的预期结果将是:

summed_df <- data.frame(
    User = c("Bill", "Fred", "John"),
    Purchases = c(4, 7, 3),
    Complaints = c(8, 5, 3),
    Data1 = c("A: 4, B: 2, C: 10", "A: 15, B: 16, C: 17", "A: 5, B: 8, C: 4"),
    Date2 = c("A: 2, B: 4, C: 6", "A: 2, B: 4, C: 6", "A: 1, B: 2, C: 3")
)

我需要以这种字符串形式返回数据。构造字符串中的数据,对所有列执行必要的计算,然后将计算的数据返回到单个列中的最佳方法是什么?

标签: rdata-structures

解决方案


这是一个凌乱的 Base R 解决方案,我确信可以改进(但得到结果):

data.frame(do.call("rbind", lapply(split(df, df$User), function(x) {
  ro <-
    data.frame(do.call("cbind", lapply(x[, grepl("^Data", names(x))], function(y) {
      paste0(c("A:", "B:", "C:"),
             colSums(do.call(
               "rbind", lapply(strsplit(trimws(
                 gsub("\\D", " ", as.character(y)), "both"
               ), "\\s+"), as.numeric)
             )),
             collapse = ", ")
    })))
  
  return(cbind(aggregate(. ~ User, x[, !grepl("^Data", names(x))], sum), ro))
})),
row.names = NULL)

推荐阅读