【问题标题】:conditional fill in values into specific row in a data table with R使用 R 有条件地将值填充到数据表中的特定行中
【发布时间】:2017-08-02 17:15:19
【问题描述】:

我有一个如下表: df

KEY    CAT      DATE   AMOUNT     VAR            VALUE
1      26    2015/10/1  1400 Event.Budget_Cat26   NA
1      26    2015/10/1  300  Event.Budget_Cat26   NA
1      26    2015/10/1  NA        NA              NA
1      22    2015/10/1  100  Event.Budget_Cat22   NA
1      22    2015/10/1  300  Event.Budget_Cat22   NA
1      22    2015/10/1  NA        NA              NA
2      21    2014/1/1   200  Event.Budget_Cat21   NA
2      21    2014/1/1   NA        NA              NA

这只是大桌子的一部分。基本上,每一行都是唯一的(KEY,CAT,DATE)。我想找到一种方法来计算基于唯一标识的金额总和,并将最终总和放入 VALUE 列。 此外,为 VAR 命名。 AMOUNT 列仅存在于 VALUE 列中,最后我将删除整个列,所以保留它,因为 NA 是可以的。

最终的结果会是这样的

KEY    CAT      DATE   AMOUNT     VAR                 VALUE
1      26    2015/10/1  1400 Event.Budget_Cat26        NA
1      26    2015/10/1  300  Event.Budget_Cat26        NA
1      26    2015/10/1  NA   Scalar.Budget_Cat26_Amt  1700
1      22    2015/10/1  100  Event.Budget_Cat22        NA
1      22    2015/10/1  300  Event.Budget_Cat22        NA
1      22    2015/10/1  NA   Scalar.Budget_Cat22_Amt   400
2      21    2014/1/1   200  Event.Budget_Cat21        NA
2      21    2014/1/1   NA   Scalar.Budget_Cat21_Amt   200

我尝试了rbind和lapply,但结果不是我想要的

df[, 4:6 := lapply(.SD, 
       function(x) replace(x, is.na(x), c("",paste("Scalar_Budget_Cat",CAT,"_Amt",sep =""),sum(x, na.rm=TRUE))), 
             KEY, .SDcols=4]

谁能帮我找出一种快速遍历包含 2,600,000 行的整个数据表的方法?谢谢你

【问题讨论】:

  • 不确定它是否很快,但请尝试df[, VALUE:=sum(AMOUNT, na.rm = T),by=list(KEY, CAT, DATE)][is.na(VAR), VAR:=paste0("Scalar_Budget_Cat",CAT,"_Amt"),]

标签: r data.table


【解决方案1】:

在按“KEY”、“CAT”、“DATE”分组后,可以使用“AMOUNT”的sum 创建“VALUE”,然后根据是否不是组的最后一个值。我们不这样做,而是使用rep 为“VALUE”列创建“AMOUNT”的NAsum,并修改“VAR”列以使每个组的最后一个元素具有“标量”子字符串

setDT(df1)[, c("VAR", "VALUE") := .(c(VAR[-.N], paste0("Scalar.", 
  sub("^[^.]+\\.", "", VAR[1]), "_Amt")), rep(c(NA, sum(AMOUNT, na.rm = TRUE)),
          c(.N-1, 1))), .(KEY, CAT, DATE)]
df1
#   KEY CAT      DATE AMOUNT                     VAR VALUE
#1:   1  26 2015/10/1   1400      Event.Budget_Cat26    NA
#2:   1  26 2015/10/1    300      Event.Budget_Cat26    NA
#3:   1  26 2015/10/1     NA Scalar.Budget_Cat26_Amt  1700
#4:   1  22 2015/10/1    100      Event.Budget_Cat22    NA
#5:   1  22 2015/10/1    300      Event.Budget_Cat22    NA
#6:   1  22 2015/10/1     NA Scalar.Budget_Cat22_Amt   400
#7:   2  21  2014/1/1    200      Event.Budget_Cat21    NA
#8:   2  21  2014/1/1     NA Scalar.Budget_Cat21_Amt   200

【讨论】:

  • 嗨阿克伦。非常感谢。它以很好的速度完成了这项工作。唯一的缺点是复杂性。我花了这么多时间来理解整个事情。非常感谢您的帮助!
  • @VeraShao 用一些解释更新了帖子
【解决方案2】:

我在 260 万行上进行了尝试,速度非常快。我们将任务分为两个操作。第一个是按KEYCATDATE 对行进行分组,然后对AMOUNT 列求和。之后我们选择is.na(VAR) == T所在的行,并用相应的字符串填充VAR列。

df[, VALUE:=sum(AMOUNT, na.rm = T),by=list(KEY, CAT, DATE)][is.na(VAR), VAR:=paste0("Scalar_Budget_Cat",CAT,"_Amt"),]

与您想要的输出不同的是,VALUE 中没有更多的NA 值。但这可以在之后使用df[!is.na(AMOUNT), VALUE:=NA,] 进行设置

【讨论】:

  • 嗨,马丁。谢谢!这是一种速度很快的简单方法。我什至没有想过我可以以这种方式使用 AMOUNT 列。谢谢!
【解决方案3】:

这是tidyverse的解决方案:

library(tidyverse)

KEY <- c(1, 1, 1, 1, 1, 1, 2, 2)
CAT <- c(26, 26, 26, 22, 22, 22, 21,21)
DATE <- c('2015/10/1', '2015/10/1', '2015/10/1', '2015/10/1', '2015/10/1', '2015/10/1', '2014/1/1', '2014/1/1')
AMOUNT <- c(1400, 300, NA, 100, 300, NA, 200, NA)
VAR <- c('Event.Budget_Cat26', 'Event.Budget_Cat26', NA, 'Event.Budget_Cat22', 'Event.Budget_Cat22', NA, 'Event.Budget_Cat21', NA)

df <- data_frame(KEY, CAT, DATE, AMOUNT, VAR, VALUE = NA)

summary_rows <- df %>%
  group_by(KEY, CAT, DATE) %>%
  summarise(VAR = paste0('Scalar.Budget_Cat', max(CAT), '_Amt'),
            VALUE = sum(AMOUNT, na.rm = T),
            AMOUNT = NA) %>%
  select(KEY, CAT, DATE, AMOUNT, VAR, VALUE) %>%
  arrange(KEY, -CAT, DATE)

df[is.na(AMOUNT),] <- summary_rows

df

##     KEY   CAT      DATE AMOUNT                     VAR VALUE
##   <dbl> <dbl>     <chr>  <dbl>                   <chr> <dbl>
## 1     1    26 2015/10/1   1400      Event.Budget_Cat26    NA
## 2     1    26 2015/10/1    300      Event.Budget_Cat26    NA
## 3     1    26 2015/10/1     NA Scalar.Budget_Cat26_Amt  1700
## 4     1    22 2015/10/1    100      Event.Budget_Cat22    NA
## 5     1    22 2015/10/1    300      Event.Budget_Cat22    NA
## 6     1    22 2015/10/1     NA Scalar.Budget_Cat22_Amt   400
## 7     2    21  2014/1/1    200      Event.Budget_Cat21    NA
## 8     2    21  2014/1/1     NA Scalar.Budget_Cat21_Amt   200

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 2019-01-27
    • 1970-01-01
    • 2020-11-06
    • 2019-03-17
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多