我有这样的数据集:
set.seed(10)
df <- data.frame(
Year = rep(2000, times=16),
Month = rep(1:2, each=8),
group = rep(c("ABC","ABc","Abc","AbC","aBC","aBc","abc", "abC"),times=2),
A_gr = rep(c("A","A","A","A","a","a","a","a"), times=2),
V = rnorm(16)
)
A,B和C可以是大写字母或小写字母。 对于每个时间点(月份+年份)和组合,我现在想要从小写字母版本中减去大写字母版本的V值。所以aBC-ABC,aBc-ABc等。
只有2封小组信件,我设法通过订单,列表和by来做到这一点,但我不能在这里工作。我也尝试过plyr,但也没有成功。有什么想法吗?
此外我想知道是否有可能在一步中从小写字母的总和中减去所有四个大写字母版本的总和,所以(aBC + aBc + abc + abC) - (ABC + ABc + Abc + ABC)
答案 0 :(得分:2)
以下是一种通过从组列中删除a
或A
信息来转换数据的方法,因为它也由A_gr
提供,然后使用tidyr
包将数据从long
转换为wide
格式,这样可以更轻松地计算差异。
library(dplyr); library(tidyr)
df %>% mutate(group = gsub("[A|a]", "", group)) %>%
spread(A_gr, V) %>% mutate(diffV = A - a) %>%
select(Year, Month, group, diffV)
Year Month group diffV
1 2000 1 bc -0.16325
2 2000 1 bC -0.23549
3 2000 1 Bc -0.57405
4 2000 1 BC -0.27580
5 2000 2 bc 0.36039
6 2000 2 bC 0.66643
7 2000 2 Bc -1.24392
8 2000 2 BC -1.38844
答案 1 :(得分:2)
我们也可以使用data.table
执行此操作。将'data.frame'转换为'data.table'(setDT(df)
),通过使用sub
将'group'中的第一个字符更改为大写来创建另一个分组变量('gr'),然后在by
和'Month'和'Year'中使用它,得到'A'和'A'中'A'对应的'V'之间的差异,并将'gr'分配给NULL(如果需要的话。)
library(data.table)
setDT(df)[, .(group = paste(group[2L],group[1L],
sep="-"),Diffs=V[A_gr=="A"]- V[A_gr=="a"]),
by = .(gr=sub("(.)", "\\U\\1", group, perl=TRUE), Month, Year)][, gr:= NULL][]
# Month Year group Diffs
#1: 1 2000 aBC-ABC -0.2757990
#2: 1 2000 aBc-ABc -0.5740468
#3: 1 2000 abc-Abc -0.1632544
#4: 1 2000 abC-AbC -0.2354917
#5: 2 2000 aBC-ABC -1.3884391
#6: 2 2000 aBc-ABc -1.2439231
#7: 2 2000 abc-Abc 0.3603894
#8: 2 2000 abC-AbC 0.6664342
通过提取“组”中的dcast
,在创建另一个变量('gr')之后,使用data.table
中的substring
从'wide'格式转换为'long'。我们对dcast
输出中的“V_A”和“V_a”列进行了区分。
setDT(df)[, gr:= substring(group, 2)]
dcast(df, Year+Month+gr~A_gr, value.var=c("V", "group"))[,
.(group = paste(group_A, group_a, sep="-"), Diffs = V_A- V_a), .(Year, Month)]
# Year Month group Diffs
#1: 2000 1 ABC-aBC -0.2757990
#2: 2000 1 ABc-aBc -0.5740468
#3: 2000 1 AbC-abC -0.2354917
#4: 2000 1 Abc-abc -0.1632544
#5: 2000 2 ABC-aBC -1.3884391
#6: 2000 2 ABc-aBc -1.2439231
#7: 2000 2 AbC-abC 0.6664342
#8: 2000 2 Abc-abc 0.3603894