R 重塑数据 - 在 table 的一部分上聚合数据以附加到另一部分

R reshaping data - aggregating data on one part of a table to append to another

我有一些调查数据,我想对其进行整形,以便能够使用过滤器进行交互式切片和切块。但是,我一直停留在如何以传统方式重塑数据,而且我无法弄清楚重塑包的适当用法。请帮忙!

数据如下:每个受访者排成一排,连同每个问题的回答。在其他列中有多个关于受访者的人口统计列。

ID  Q1  Q2  Q3  …   Q30 Demo1   Demo2   Demo3 Average Score
1   1   2   2   …   2   1       1       1     2.5
2   2   3   1   …   5   1       2       1     2.7
3   4   1   5   …   4   2       3       2     1.6
4   1   5   4   …   3   2       1       2     2.5
5   3   4   4   …   1   1       2       2     1.4

目标是重塑数据,使每个独特的 question/demographic 组合都是独一无二的,并将该组合的得分 average/sample 作为值。

Question    Demo1   Demo2   Demo3   Average NumResp
1           1       1       1       3.4     2
1           1       1       2       2.3     5
1           1       1       3       3.1     1
…           …       …       …       …       ...
30          4       5       3       1.3     9

作为问题的第 2 部分,还有一些计算将 1-5 等级的响应更改为 "positive"、"neutral" 或 "negative"。最好将其添加为一列,显示该特定人口统计中所有受访者的百分比是三个值之一,所有 3 个值加起来为 100%。

Q   Sentiment   Demo1   Demo2   Demo3   Average
1   Positive    1       1       1       3.4
1   Neutral     1       1       1       2.3
1   Negative    1       1       1       3.1
…       …   …   …   …
30  Negative    4       5       3       1.3

非常感谢任何帮助!更愿意在 R 中执行此操作,尽管 Python 也可以。

假设您有这样的数据集(使其成为 data.table): ID Q1 Q2 ... Demo1 Demo2 Demo3 1: 1 7 8 2 7 3 2: 2 3 7 6 10 1 3: 3 6 1 5 5 8 4: 4 5 9 10 1 7 5: 5 10 4 8 4 6 和答案字典分数: value Question Score 1: 7 1 17 2: 3 1 6 3: 6 1 19 让我们将数据转换为问题、答案、ID、演示:

d2 <- melt(dt, id.vars=c('ID', 'Demo1', 'Demo2', 'Demo3'), measure.vars=grep('^Q[0-9]+$', colnames(dt), val=T)) d2[, c('Question', 'variable'):=list(substring(variable,2), NULL)] R> d2 ID Demo1 Demo2 Demo3 value Question 1: 1 2 7 3 7 1 2: 2 6 10 1 3 1 3: 3 5 5 8 6 1 现在让我们添加分数: d3 <- merge(d2, vals_enc, by=c('Question', 'value')) 最后得到问题和人口统计的平均分数和受访者: d3[, list(Avg=mean(Score), Number=.N), .(Question,Demo1,Demo2,Demo3)] Question Demo1 Demo2 Demo3 Avg Number 1: 1 6 10 1 6 1 2: 1 10 1 7 18 1 3: 1 5 5 8 19 1

注意: 对于每个 ID 都有相同的人口统计状态,因此人口统计和问题的每个组合的受访者数量应该相同。

关于问题的第 2 部分: 你有这样的计算或者你正在寻找它们吗?

使用 melt 我们可以指定 id 变量(分组)或度量变量(折叠到 "long")。参数 variable.name 允许我们命名通过折叠宽列创建的新变量。 value.name 允许我们命名值列。 ?melt.data.frame.

的文档提供了所有这些以及更多内容

为了创建 Sentiment 变量,我们使用 cut 将分数的值范围分成三分之一。有一个名为 labels 的参数允许我们选择新值的名称。

library(reshape2)
m <- melt(df, variable.name="Question", value.name="Average", id=c("Demo1", "Demo2", "Demo3"))
m$Question <- gsub("Q", "", m$Question)
a <- aggregate(Average~., m, mean)
a$Sentiment <- cut(a$Average, seq(1,5,length.out=4), labels=c("Negative", "Neutral", "Postive"), include.lowest=T)
#    Demo1 Demo2 Demo3 Question Average Sentiment
# 1      1     1     1        1       1  Negative
# 2      1     2     1        1       2  Negative
# 3      2     1     2        1       1  Negative
# 4      1     2     2        1       3   Neutral
# 5      2     3     2        1       4   Postive
# 6      1     1     1        2       2  Negative
# 7      1     2     1        2       3   Neutral
# 8      2     1     2        2       5   Postive
# 9      1     2     2        2       4   Postive
# 10     2     3     2        2       1  Negative

请注意,我删除了 "ID" 和 "Average.Score" 列,因为它们将在此过程中重新计算。

数据

df <- read.table(text="
ID  Q1  Q2  Q3     Q30 Demo1   Demo2   Demo3 Average.Score
1   1   2   2      2   1       1       1     2.5
2   2   3   1      5   1       2       1     2.7
3   4   1   5      4   2       3       2     1.6
4   1   5   4      3   2       1       2     2.5
5   3   4   4      1   1       2       2     1.4", header=T)

df <- df[,!names(df) %in% c("ID", "Average.Score")]