当我想要携带多个度量变量时,我无法找出将数据从长格式转换为宽格式的最优雅和灵活的方法.
例如,这是一个长格式的简单数据框. ID是主体,TIME是时间可变的,并且X和Y是由测量X在Y:
> my.df <- data.frame(ID=rep(c("A","B","C"), 5), TIME=rep(1:5, each=3), X=1:15, Y=16:30)
> my.df
ID TIME X Y
1 A 1 1 16
2 B 1 2 17
3 C 1 3 18
4 A 2 4 19
5 B 2 5 20
6 C 2 6 21
7 A 3 7 22
8 B 3 8 23
9 C 3 9 24
10 A 4 10 25
11 B 4 11 26 …Run Code Online (Sandbox Code Playgroud) 我有一个很长的数据集我想扩大,我很好奇是否有一种方法可以使用R中的reshape2或tidyr包一步完成所有这些操作.
数据框df如下所示:
id type transactions amount
20 income 20 100
20 expense 25 95
30 income 50 300
30 expense 45 250
Run Code Online (Sandbox Code Playgroud)
我想谈谈这个问题:
id income_transactions expense_transactions income_amount expense_amount
20 20 25 100 95
30 50 45 300 250
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过reshape2来获得部分路径,例如:
dcast(df, id ~ type, value.var="transactions")
Run Code Online (Sandbox Code Playgroud)
但有没有办法一次性重塑整个df,同时解决"交易"和"金额"变量?理想情况下,新的更合适的列名称?
以下是此示例的玩具数据集:
data <- data.frame(x=rep(c("red","blue","green"),each=4), y=rep(letters[1:4],3), value.1 = 1:12, value.2 = 13:24)
x y value.1 value.2
1 red a 1 13
2 red b 2 14
3 red c 3 15
4 red d 4 16
5 blue a 5 17
6 blue b 6 18
7 blue c 7 19
8 blue d 8 20
9 green a 9 21
10 green b 10 22
11 green c 11 23
12 green d 12 24
Run Code Online (Sandbox Code Playgroud)
如何转换或传播变量y,以生成以下宽数据.frame:
x a.value.1 b.value.1 c.value.1 …Run Code Online (Sandbox Code Playgroud) 为什么不能在一个有多个变量传递给value.var在dcast?来自?dcast:
value.var存储值的列的名称,请参阅guess_value以了解默认策略.
它没有明确指出只能将一个变量作为值传递给它.但是,如果我尝试,那么我得到一个错误:
> library("reshape2")
> library("MASS")
>
> dcast(Cars93, AirBags ~ DriveTrain, mean, value.var=c("Price", "Weight"))
Error in .subset2(x, i, exact = exact) : subscript out of bounds
In addition: Warning message:
In if (!(value.var %in% names(data))) { :
the condition has length > 1 and only the first element will be used
Run Code Online (Sandbox Code Playgroud)
那么有没有理由强加这种限制?是否有可能解决这个问题(也许使用reshape等)?
reshape2是一个允许强大的数据转换数组的包,通过它的两部分熔化/铸造方法。然而,像所有工具一样,它嵌入了限制它可以处理的情况的假设。
哪些数据重塑问题reshape2无法以当前形式处理?
理想的答案将包括:
reshape2)例子
“宽”数据在面板应用中很常见。
melt.wide <- function(data, id.vars, new.names, sep=".", variable.name="variable", ... ) {
# Guess number of variables currently wide
colnames(data) <- sub( paste0(sep,"$"), "", colnames(data) )
wide.vars <- colnames(data)[grep( sep, colnames(data) )]
n.wide <- str_count( wide.vars, sep )
stopifnot(length(new.names)==unique(n.wide))
# Melt
data.melt <- melt(data,id.vars=id.vars,measure.vars=wide.vars,...)
new <- stack.list(str_split(data.melt$variable,sep))
colnames(new) <- c(variable.name,new.names)
data.melt <- subset(data.melt,select=c(-variable))
cbind(data.melt,new)
}
choice.vars <- colnames(res)[grep("_",colnames(res))]
melt.wide( subset(res,select=c("WorkerId",choice.vars)), id.vars="WorkerId", new.names=c("set","option"), sep="_")
Run Code Online (Sandbox Code Playgroud)
新函数返回一个熔化的对象,然后可以是*cast.
数据在哪里:
so <- …Run Code Online (Sandbox Code Playgroud)