按列表中的元素重新排序列表并删除列表中的指定行
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 的解决方案以及整个清理和总结过程将变得更加清晰和容易。
继续这个问题:
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 的解决方案以及整个清理和总结过程将变得更加清晰和容易。