按列表中的元素重新排序列表并删除列表中的指定行

Reordering a list by element in list and remove specified rows in list

继续这个问题:

testing <- data.frame(
  MONTH = c("MTD: 12", "MTD: 12", "MTD: 11", "MTD: 12", "MTD: 12", "MTD: 12"), 
  YEAR = c(2012, 2013, 2014, 2015, 2013, 2014), 
  Client = c("A.", "A.", "A.", "B.", "B.", "B."), 
  Revenue = c(320, 205, 166L, 152, 150, 138),
  Col1 = c(651, 485, 533, 3932, 171, 436), 
  Col2 = c(478, 335, 305, 238, 115, 251), 
  Col3 = c(73, 69, 57, 6, 67, 57), 
  Col4 = c(6.7, 6.1, 5.5, 6.4, 13.1, 5.5)
)

# subset just the month=12 rows
test12 <- testing[testing$MONTH=="MTD: 12", ]
test12 <- test12[order(test12$Client, test12$YEAR), ]

# define a function to calculate percent change
pctchange <- function(x) {
  L <- length(x)
  c(NA, 100 * (x[-1] - x[-L]) / x[-L])
}

# calculate percent change for all columns, by client
change <- apply(test12[, c("Revenue", "Col1", "Col2", "Col3", "Col4")], 2,
  function(y) unlist(tapply(y, test12$Client, pctchange)))
change <- data.frame(change)
names(change) <- paste0("d", names(change))
test12b <- cbind(test12[, c("MONTH", "YEAR", "Client")], change)

# merge back with monthly data
merge(testing, test12b, all=TRUE)

因此,在 运行 执行此代码后,您将获得一个已被客户端拆分的列表。

我想 运行 下面的代码,如果该因素(客户端)的行数大于 2,则基本上会删除第二行。

我已经试过了,但没用:

testing<-ifelse(length(splitresult)>2,splitresult[-2,],splitresult)

所有这一切的最终目标:

1) 只获取去年与前一年的百分比变化,而不显示前一年的 NA 等中间值。但如果它是一个新客户,我确实希望那里的 NA 指定它是一个新客户。所以这就是为什么我尝试了上面没有工作的代码。

2) 我想按 MTD 中的收入对拆分中的客户重新排序:2014 年 12 日。

splitlist[order(sapply(splitlist, function(x) (x[["Revenue"]])))]

(无效:假设 splitlist 是列表的名称)

如果有人可以帮助我解决这两个问题,那将非常有帮助。谢谢!

我认为 plyr 软件包在这里会有所帮助。例如,您可以尝试使用

而不是最后一行使用 ifelse 的代码
library(plyr)
out = ddply(splitresult, "Client", function(x){
  if(dim(x)[1] > 2) x = x[-2,]
  return(x)
})

这里,x是一个client-specific数据框,out是一堆client-specific数据框的行合并的结果

您也可以查看 lubridate,这将使日期和时间更容易处理。正如评论中所提到的,dplyr 也会有所帮助,其余的 "Hadleyverse" 包也有帮助,用于清理和绘制数据。使用正确的工具,问题 1 和 2 的解决方案以及整个清理和总结过程将变得更加清晰和容易。