【问题标题】:aggregate function in R, multiple conditionsR中的聚合函数,多个条件
【发布时间】:2015-10-29 19:02:44
【问题描述】:

我没有得到正确的方法来计算一个新列,该列包含一个数据框中的列的总和,方法是通过 grep 函数聚合另一个列。数据框如下所示:

   ID_Oeffnungszeit ID_Einrichtung Anzahl_Std Bez_Oeffnungszeit
                 1        3000001       0.50  Montag Vormittag
                 1        3000003       3.00  Montag Vormittag
                 1        3000008       2.50  Montag Vormittag
                 2        3000001       1.00  Montag Nachmittag
                 4        3000003       1.50  Dienstag Vormittag
                 1        3000023       1.00  Montag Vormittag
                 1        3000025       1.00  Montag Vormittag
                 1        3000026       1.00  Montag Vormittag
                 3        3000001       2.00  Montag Abend
                            ...
                 1        3000038       3.50  Montag Vormittag
                          and so on...

变量Bez_Oeffnungszeit有21个特征,但如果包含VormittagNachmittagAbend这几个词,就可以归类。 所以我想生成一个新列,其中包含每个ID_Einrichtung 的列Anzahl_Std 的总和,具体取决于Bez_Oeffnungszeit 包含的单词。

我很确定我应该使用 grepby 函数,但我无法让它在我的意义上发挥作用......

df <- structure(list(ID_Oeffnungszeit = c("1", "1", "1", "2", "4", 
"1", "1", "1", "3"), ID_Einrichtung = c(3000001L, 3000003L, 3000008L, 
3000001L, 3000003L, 3000023L, 3000025L, 3000026L, 3000001L), 
    Anzahl_Std = c(0.5, 3, 2.5, 1, 1.5, 1, 1, 1, 2), Bez_Oeffnungszeit = c("Montag Vormittag", 
    "Montag Vormittag", "Montag Vormittag", "Montag Nachmittag", 
    "Dienstag Vormittag", "Montag Vormittag", "Montag Vormittag", 
    "Montag Vormittag", "Montag Abend")), .Names = c("ID_Oeffnungszeit", 
"ID_Einrichtung", "Anzahl_Std", "Bez_Oeffnungszeit"), class = "data.frame", row.names = c(NA, 
-9L))

【问题讨论】:

  • 如果您使用dput 来包含示例数据会有所帮助,特别是因为您在最后一列中有空格。
  • 我为前几行添加了 dput

标签: r data-management


【解决方案1】:

我认为最简单的方法是创建一个仅包含单词“Vormittag”、“Nachmittag”或“Abend”的新列,然后将其用作分组变量。

例如:

# Set random seed for reproducibility
set.seed(12345)

# Make some data
my.data <- data.frame(ID_Oeffnungszeit = sample(1:10, 100, replace = TRUE),
                   ID_Einrichtung = sample(3000001:3000020, 100, replace = TRUE),
                   Anzahl_Std = rnorm(100),
                   Bez_Oeffnungszeit = sample(c("Montag Vormittag",
                                                "Montag Nachmittag",
                                                "Dienstag Vormittag", 
                                                "Montag Abend"), 100, 
                                                replace = T))

# Create a new column containing "Vormittag", "Nachmittag" or "Abend"
my.data$cat <- ""
my.data$cat[grep("Vormittag", my.data$Bez_Oeffnungszeit)] <- "Vormittag"
my.data$cat[grep("Nachmittag", my.data$Bez_Oeffnungszeit)] <- "Nachmittag"
my.data$cat[grep("Abend", my.data$Bez_Oeffnungszeit)] <- "Abend"

# Now just call aggregate over the Std variable using ID and category
# as grouping factors.
res <- aggregate(my.data$Anzahl_Std, 
                 by = list(ID = my.data$ID_Einrichtung, cat = my.data$cat), 
                 FUN = sum)

【讨论】:

  • 非常感谢,这正是我想要的!
  • 补充: 是否有可能只将结果的子集版本放入新的 df 中?例如只是my.data$cat["Vormittag"] 的行。你能不能也用 ddply 来指路?我试过:res &lt;- ddply(my.data, .(ID_Oeffnugszeit, cat["Ja"]), sum(Anzahl_Std)),但它是错误的。但是,ddply 似乎更适合这样的聚合..
【解决方案2】:

这是另一个选项(使用问题中提到的数据)

library(splitstackshape)

步骤一:使用 splitstackshape 的 cSplit 函数将列 Bez_Oeffnungszeit 拆分为 wide 格式,利用两个单词之间的空格。 这将生成两列 'Bez_Oeffnungszeit_1' 包含第一个单词,'Bez_Oeffnungszeit_2' 包含第二个单词,在第二步中进一步使用

dt = cSplit(df, 'Bez_Oeffnungszeit', ' ', 'wide') 

第二步:我们使用包含感兴趣的词的'Bez_Oeffnungszeit_2''ID_Einrichtung'列使用data.table语法对'Anzahl_Std'求和

dt[order(Bez_Oeffnungszeit_2), .(New = sum(Anzahl_Std)), 
            by = .(ID_Einrichtung, Bez_Oeffnungszeit_2)]

#output looks like:

#   ID_Einrichtung Bez_Oeffnungszeit_2 New
#1:        3000001               Abend 2.0
#2:        3000001          Nachmittag 1.0
#3:        3000001           Vormittag 0.5
#4:        3000003           Vormittag 4.5
#5:        3000008           Vormittag 2.5
#6:        3000023           Vormittag 1.0
#7:        3000025           Vormittag 1.0
#8:        3000026           Vormittag 1.0

【讨论】:

  • 不熟悉splitstackshape,你能解释一下代码在做什么吗? Bez_Oeffnungszeit_2 来自哪里?
  • @nico 我已将描述添加到我的答案中。希望我说得够清楚
猜你喜欢
  • 2020-01-07
  • 2016-05-02
  • 2020-02-18
  • 1970-01-01
  • 2017-02-19
  • 2017-11-25
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
相关资源
最近更新 更多