Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建一个新表,显示R中单个列的两个不同类别之间的百分比变化_R_Reshape2_Dcast - Fatal编程技术网

创建一个新表,显示R中单个列的两个不同类别之间的百分比变化

创建一个新表,显示R中单个列的两个不同类别之间的百分比变化,r,reshape2,dcast,R,Reshape2,Dcast,我试图学习如何使用R“Reformae2”包中的一些函数,特别是dcast。我试图创建一个表,显示两个软件版本的聚合和(所有文件的一类数据之和除以一个“案例”中的最大“RepNum”)以及两者之间的百分比变化 以下是我的数据集的外观(示例数据): 实际数据集有6个唯一文件、两个最早的“TestNums&Versions”、2个唯一类别和4个唯一案例 利用互联网的魔力,我能够拼凑出一张类似于这样的表格,以满足不同的需求(但代码应该是类似的): 这是生成该表的代码: vLatest和vPreviou

我试图学习如何使用R“Reformae2”包中的一些函数,特别是
dcast
。我试图创建一个表,显示两个软件版本的聚合和(所有文件的一类数据之和除以一个“案例”中的最大“RepNum”)以及两者之间的百分比变化

以下是我的数据集的外观(示例数据):

实际数据集有6个唯一文件、两个最早的“TestNums&Versions”、2个唯一类别和4个唯一案例

利用互联网的魔力,我能够拼凑出一张类似于这样的表格,以满足不同的需求(但代码应该是类似的):

这是生成该表的代码:

vLatest和vPrevious是具有最新和第二最新verion编号的变量

注:四舍五入和百分号为加号,但为首选加号

这些数字并不能反映正确完成的实际数学运算,只是我放在里面的随机数字,作为例子。我满怀希望地解释了我正在努力做的数学题

要测试的示例数据集

FileName<-rep(c("File1","File2","File3","File4","File5","File6"),times=8,each=6)
Version<-rep(c("1.0.18","1.0.21"),times=4,each=36)
Category<-rep(c("Category1","Category2"),times=48,each=3)
Value<-rpois(n=288,lambda=32)
TestNum<-rep(11:12,times=4,each=36)
RepNum<-rep(1:3,times=96)
Case<-rep(c("Case1","Case2","Case3","Case4"),each=72)
df<-data.frame(FileName,Version,Category,Value,TestNum,RepNum,Case)
当我试着这样做的时候:

pc <- function(a,b) (b-a)/a
summary <- df %>% 
  group_by(Case, Category, Version) %>% 
  summarize(Value=mean(Value)) %>% 
  spread(Version, Value) %>% 
  mutate(Change=scales::percent(pc(vPrevious,vLatest)))

(我没有对OP提供的示例数据集使用“
prevetestnum的原因是,通过分析编辑,我相信下面的代码甚至可以使用OP的生产数据集生成所需的结果

我的理解是OP有一个data.frame,其中包含许多测试结果,但他只想显示两个最新版本的相对变化

OP已请求帮助使用
dcast()
函数。此函数可从两个软件包中获得,
Reforme2
data.table
。这里的
data.table
版本用于快速和简洁的代码。此外,还使用了
forcats
formattable
软件包中的函数

library(data.table)   # CRAN version 1.10.4 used
# coerce to data.table object
DT <- data.table(df)
# reorder factor levels of Version according to TestNum
DT[, Version := forcats::fct_reorder(Version, TestNum)]
# determine the two most recent Versions
# trick: pick 1st and 2nd entry of the _reversed_ levels
vLatest <- DT[, rev(levels(Version))[1L]]
vPrevious <- DT[, rev(levels(Version))[2L]]
# filter DT, reshape from long to wide format, 
# compute change for the selected columns using get(),
# use formattable package for pretty printing
summary <- dcast(
  DT[Version %in% c(vLatest, vPrevious)], 
  Case + Category ~ Version, mean, value.var = "Value")[
    , PercentChange := formattable::percent(get(vLatest) / get(vPrevious) - 1.0)]
summary
解释 排序
版本
OP已经认识到,简单地按字母顺序排序
版本
并不能确保正确的顺序。这可以通过

sort(paste0("0.0.", 0:12))
其中
0.0.10
位于
0.0.2
之前

这一点至关重要,因为默认情况下,
data.frame()
会将字符变量转换为因子

幸运的是,
TestNum
Version
关联。因此,
TestNum
forcats
包中的
fct\u reorder()
函数的帮助下,用于对
Version
的因子级别进行重新排序

这还确保
dcast()
以适当的顺序创建新列

通过变量访问列 在表达式中使用
vLatest/vPrevious
,将返回错误消息

vLatest/vPrevious中出错:二进制运算符的非数值参数

这是意料之中的,因为
vLatests
vPrevious
包含字符值
“1.0.21”
“1.0.18”“
,不可分割。这里的意思是取列的值,这些列的名称由
vLatests
vPrevious
和divide给出。这是通过使用
get()
实现的

格式设置为百分比 当
scales::percent()
返回字符向量时,
formattable::percent()
确实返回带有百分比表示的数字向量,也就是说,我们仍然能够进行数字计算

资料 正如OP给出的:

FileName <- rep(c("File1", "File2", "File3", "File4", "File5", "File6"),
                times = 8, each = 6)
Version <- rep(c("1.0.18", "1.0.21"), times = 4, each = 36)
Category <- rep(c("Category1", "Category2"), times = 48, each = 3)
Value <- rpois(n = 288, lambda = 32)
TestNum <- rep(11:12, times = 4, each = 36)
RepNum <- rep(1:3, times = 96)
Case <- rep(c("Case1", "Case2", "Case3", "Case4"), each = 72)
df <- data.frame(FileName, Version, Category, Value, TestNum, RepNum, Case)

FileName@MrFlick编辑中没有新问题。我在原始问题中提到了
vLatest
vPrevious
变量。
vLatest<-unique(df[df[,"TestNum"] == max(df$TestNum), "Version"])
vPrevious<-unique(df[df[,"TestNum"] == sort(unique(df$TestNum), T)[2], "Version"])
pc <- function(a,b) (b-a)/a
summary <- df %>% 
  group_by(Case, Category, Version) %>% 
  summarize(Value=mean(Value)) %>% 
  spread(Version, Value) %>% 
  mutate(Change=scales::percent(pc(vPrevious,vLatest)))
maxTestNum<-max(df$TestNum)
prevTestNum<-sort(unique(df$TestNum), T)[2]
library(data.table)   # CRAN version 1.10.4 used
# coerce to data.table object
DT <- data.table(df)
# reorder factor levels of Version according to TestNum
DT[, Version := forcats::fct_reorder(Version, TestNum)]
# determine the two most recent Versions
# trick: pick 1st and 2nd entry of the _reversed_ levels
vLatest <- DT[, rev(levels(Version))[1L]]
vPrevious <- DT[, rev(levels(Version))[2L]]
# filter DT, reshape from long to wide format, 
# compute change for the selected columns using get(),
# use formattable package for pretty printing
summary <- dcast(
  DT[Version %in% c(vLatest, vPrevious)], 
  Case + Category ~ Version, mean, value.var = "Value")[
    , PercentChange := formattable::percent(get(vLatest) / get(vPrevious) - 1.0)]
summary
    Case  Category   1.0.18   1.0.21 PercentChange
1: Case1 Category1 33.00000 31.94444        -3.20%
2: Case1 Category2 31.83333 31.83333         0.00%
3: Case2 Category1 33.05556 33.61111         1.68%
4: Case2 Category2 30.77778 32.94444         7.04%
5: Case3 Category1 33.16667 31.94444        -3.69%
6: Case3 Category2 33.44444 33.72222         0.83%
7: Case4 Category1 30.83333 34.66667        12.43%
8: Case4 Category2 32.27778 33.44444         3.61%
sort(paste0("0.0.", 0:12))
 [1] "0.0.0"  "0.0.1"  "0.0.10" "0.0.11" "0.0.12" "0.0.2"  "0.0.3"  "0.0.4"  "0.0.5" 
[10] "0.0.6"  "0.0.7"  "0.0.8"  "0.0.9"
FileName <- rep(c("File1", "File2", "File3", "File4", "File5", "File6"),
                times = 8, each = 6)
Version <- rep(c("1.0.18", "1.0.21"), times = 4, each = 36)
Category <- rep(c("Category1", "Category2"), times = 48, each = 3)
Value <- rpois(n = 288, lambda = 32)
TestNum <- rep(11:12, times = 4, each = 36)
RepNum <- rep(1:3, times = 96)
Case <- rep(c("Case1", "Case2", "Case3", "Case4"), each = 72)
df <- data.frame(FileName, Version, Category, Value, TestNum, RepNum, Case)