-1

我正在尝试rowSum为实际列做一个。但是,我想包括UpTo某些观察的最新值。这是数据框:

dat <- structure(list(Company = c("ABC", "DEF", "XYZ"), UpTo = c(NA, 
"Q2", "Q3"), Actual.Q1 = c(100L, 80L, 100L), Actual.Q2 = c(50L, 
75L, 50L), Forecast.Q3 = c(80L, 50L, 80L), Forecast.Q4 = c(90L, 
80L, 100L)), .Names = c("Company", "UpTo", "Actual.Q1", "Actual.Q2", 
"Forecast.Q3", "Forecast.Q4"), class = "data.frame", row.names = c("1", 
"2", "3"))

  Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4
1     ABC   NA       100        50          80          90
2     DEF   Q2        80        75          50          80
3     XYZ   Q3       100        50          80         100
  • 对于 company ABC,由于没有UpTo日期,它只是Actual.Q1+ Actual.Q2,即 150。
  • 对于 company DEF,因为UpTo日期是Q2,所以它将是Actual.Q1+ Actual.Q2,即 155。
  • 对于 company XYZ,因为UpTo日期是Q3,所以它将是Actual.Q1++ ,即 230 Actual.Q2Forecast.Q3

生成的数据框如下所示:

  Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4 SumRecent
1     ABC   NA       100        50          80          90       150
2     DEF   Q2        80        75          50          80       155
3     XYZ   Q3       100        50          80         100       230

我已经尝试使用该rowSums功能。但是,它不会使变量 生效UpTo。任何帮助表示赞赏。谢谢!

4

4 回答 4

1

我们可以使用二进制加权行和。

UpTo <- as.character(dat$UpTo)  ## in case you have factor column
UpTo[is.na(UpTo)] <- "Q2"  ## replace `NA` to "Q2"
w <- outer(as.integer(substr(UpTo, 2, 2)), 1:4, ">=")
#     [,1] [,2]  [,3]  [,4]
#[1,] TRUE TRUE FALSE FALSE
#[2,] TRUE TRUE FALSE FALSE
#[3,] TRUE TRUE  TRUE FALSE

我们有一个逻辑矩阵。但它不会像TRUE1 和FALSE0 那样影响算术计算。然后我们进行加权行求和:

X <- data.matrix(dat[3:6])
dat$SumRecent <- rowSums(X * w)

#  Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4 SumRecent
#1     ABC <NA>       100        50          80          90       150
#2     DEF   Q2        80        75          50          80       155
#3     XYZ   Q3       100        50          80         100       230

这种方法的优点是它的速度/效率,因为它是完全矢量化的。这个方法超级快。您可以参考快速方式的基准测试结果来创建一个二进制矩阵,其中 R 中的每行已知数量为 1

于 2016-11-23T18:10:35.387 回答
1

这是一种可能性:

df$SumRecent <- sapply(1:nrow(df), function(x) {sum(df[x,3:ifelse(is.na(grep(df[x,2], colnames(df))[1]), 4, grep(df[x,2], colnames(df))[1])])})


#   Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4 SumRecent
# 1     ABC <NA>       100        50          80          90       150
# 2     DEF   Q2        80        75          50          80       155
# 3     XYZ   Q3       100        50          80         100       230

我们正在寻找与( ) 的列名称中的( ) 列grep中的值相匹配的使用。如果我们找到它,我们就会得到总和,如果我们没有找到它,我们只需将第 3 列和第 4 列中的值相加。UpTodf[x,2]dfcolnames(df)

于 2016-11-23T18:10:38.040 回答
0

这也应该有效:

df$UpTo <- as.character(df$UpTo)
df$SumRecent <- apply(df, 1, function(x) ifelse(is.na(x[2]), sum(as.integer(x[3:4])), 
                                           sum(as.integer(x[3:(grep(x[2], names(df)))]))))
df

#     Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4 SumRecent
#1     ABC <NA>       100        50          80          90       150
#2     DEF   Q2        80        75          50          80       155
#3     XYZ   Q3       100        50          80         100       230
于 2016-11-23T18:23:45.120 回答
0

使用数据表的另一种方法:

require(data.table)
dat <- fread('Company UpTo Actual.Q1 Actual.Q2 Forecast.Q3 Forecast.Q4
             ABC   NA       100        50          80          90
             DEF   Q2        80        75          50          80
             XYZ   Q3       100        50          80         100')

dat[, SumRecent:= ifelse(is.na(UpTo), Actual.Q1 + Actual.Q2,  
                                      sum(.SD[, grepl(paste0("Q[1-", substring(UpTo, 2), "]$"), names(.SD)), with = F]) ), by = Company]
于 2016-11-24T15:57:57.970 回答