假设我们在调查中有两个问题,一个是关于个人推荐公司的可能性(假设有两家公司为了简单起见)。
所以,我有一个带有2列的data.frame:
df.recommend <- data.frame(rep(1:5,20),rep(1:5,20))
colnames(df.recommend) <- c("Company1","Company2")
并且,假设我们还有另一个问题,要求受访者在他们认为与公司“适合”的属性旁边勾选一个方框。
所以,我有另外一个包含4列的data.frame:
df.attribute <- data.frame(rep(0:1,50),rep(1:0,50),rep(0:1,50),rep(1:0,50))
colnames(df.attribute) <- c(
"Attribute1.Company1",
"Attribute2.Company1",
"Attribute1.Company2",
"Attribute2.Company2")
现在,我希望能够做的是审查属性1和2如何与所有公司(公司独立)推荐问题的可能性的规模相关。只是想知道那些极有可能推荐的人和例如1的属性之间的惯性。
所以,我首先将两个问题绑定在一起:
df <- cbind(df.recommend, df.attribute)
我的问题是试图找出如何堆叠这些数据,使列看起来像:
df.stacked <- data.frame(c(df$Company1,df$Company2),
c(df$Attribute1.Company1,df$Attribute1.Company2),
c(df$Attribute2.Company1,df$Attribute2.Company2))
colnames(df.stacked) <- c("Likelihood","Attribute1","Attribute2")
此示例在很大程度上得到了简化。在我的实际问题中,我有34家公司和24个属性。
你能想出一种有效堆叠它们的方法,而不必输入所有的c()语句吗?
注意:可能性的列模式是Co1,Co2,Co3,Co4 ......属性的模式是At1.Co1,At2.Co1,At3.Co1 ... At1.Co34,At2.Co34。 ..
答案 0 :(得分:4)
对于这类问题,Hadley的重塑包是完美的工具。我将它与一些stringr和plyr语句(也是Hadley编写的包)结合起来。
以下是我认为是十几行代码的完整解决方案。
首先,创建一些数据
library(reshape2) # EDIT 1: reshape2 is faster
library(stringr)
library(plyr)
# Create data frame
# Important: note the addition of a respondent id column
df_comp <- data.frame(
RespID = 1:10,
Company1 = rep(1:5, 2),
Company2 = rep(1:5, 2)
)
df_attr <- data.frame(
RespID = 1:10,
Attribute1.Company1 = rep(0:1,5),
Attribute2.Company1 = rep(1:0,5),
Attribute1.Company2 = rep(0:1,5),
Attribute2.Company2 = rep(1:0,5)
)
现在开始数据操作:
# Use melt to convert data from wide to tall
melt_comp <- melt(df_comp, id.vars="RespID")
melt_comp <- rename(melt_comp, c(variable="comp", value="likelihood"))
melt_attr <- melt(df_attr, id.vars="RespID")
# Use str_split to split attribute variables into attribute and company
# "." period needs to be escaped
# EDIT 2: reshape::colsplit is simpler than str_split
split <- colsplit(melt_attr$variable, "\\.", names=c("attr", "comp"))
melt_attr <- data.frame(melt_attr, split)
melt_attr$variable <- NULL
# Use cast to convert from tall to somewhat tall
cast_attr <- cast(melt_attr, RespID + comp ~ attr, mean)
# Combine data frames using join() in package plyr
df <- join(melt_comp, cast_attr)
head(df)
输出:
RespID comp likelihood Attribute1 Attribute2
1 1 Company1 1 0 1
2 2 Company1 2 1 0
3 3 Company1 3 0 1
4 4 Company1 4 1 0
5 5 Company1 5 0 1
6 6 Company1 1 1 0
答案 1 :(得分:1)
我快点做的东西。看起来不是最好并使用for循环,但这不应该是只有24个值的问题
df.recommend <- data.frame(rep(1:5,20),rep(1:5,20))
colnames(df.recommend) <- c("Co1","Co2")
df.attribute <- data.frame(rep(0:1,50),rep(1:0,50),rep(0:1,50),rep(1:0,50))
colnames(df.attribute) <- c(
"At1.Co1",
"At2.Co1",
"At1.Co2",
"At2.Co2")
df.stacked <- data.frame(
likelihood <- unlist(df.recommend)
)
str <- strsplit(names(df.attribute),split="\\.")
atts <- unique(sapply(str,function(x)x[1]))
for (i in 1:length(atts))
{
df.stacked[,i+1] <- unlist(df.attribute[sapply(str,function(x)x[1]==atts[i])])
}
names(df.stacked) <- c("likelihood",paste("attribute",1:length(atts),sep=""))
编辑:它假定公司对每个属性的顺序相同