我正在寻找一些有关数据重组的建议。我正在使用 Google Forms 收集一些数据,我将其下载为 csv 文件,如下所示:
# alpha beta option
# 6 8, 9, 10, 11 apple
# 9 6 pear
# 1 6 apple
# 3 8, 9 pear
# 3 6, 8 lime
# 3 1 apple
# 2, 4, 7, 11 9 lime
数据有两个变量(alpha 和 beta),每个变量都列出数字。对于我的大部分数据,每个变量中只有一个数字。然而,对于某些观察结果,可能有两个、三个甚至多达十个数字。这是因为这些是使用谷歌表单中的“复选框”选项收集的回复,该选项允许对一个调查问题提供多个答案。此外,对于某些潜在的解决方案来说,谷歌表单在每个多个答案之前返回前导空格可能很重要。
在我的真实数据中,这种情况只发生在所有观察中的很小一部分,上面是一个更简洁的例子。数据集中还有其他几个变量。在这里我只包括一个名为“选项”的包含因素。
我需要做的是复制“alpha”或“beta”变量中包含多个数字的所有观察结果。重复行的数量应等于 alpha 或 beta 变量中存在的数字数量。然后,我需要用每个数字独立替换“alpha”或“beta”变量中的数字序列。这会导致类似下面的结果:
# alpha beta option
# 6 8 apple
# 6 9 apple
# 6 10 apple
# 6 11 apple
# 9 6 pear
# 1 6 apple
# 3 8 pear
# 3 9 pear
# 3 6 lime
# 3 8 lime
# 3 1 apple
# 2 9 lime
# 4 9 lime
# 7 9 lime
# 11 9 lime
这是再现上面原始示例数据的数据。我将数据框称为“演示”:
demo<-structure(list(alpha = structure(c(4L, 5L, 1L, 3L, 3L, 3L, 2L), .Label =
c("1","2, 4, 7, 11", "3", "6", "9"), class = "factor"), beta = structure(c(5L, 2L, 2L,
4L, 3L, 1L, 6L), .Label = c("1", "6", "6, 8", "8, 9", "8, 9, 10, 11", "9"), class =
"factor"), option = structure(c(1L, 3L, 1L, 3L, 2L, 1L, 2L), .Label = c("apple",
"lime", "pear"), class = "factor")), .Names = c("alpha", "beta", "option"), class =
"data.frame", row.names = c(NA, -7L))
好的。所以我认为我已经编写了一些代码,这些代码以非常冗长的方式确实导致了我正在寻找的新数据框。然而,感觉必须有一种更优雅、更好的方法来做到这一点。
基本上,我首先处理“alpha”变量。我首先根据变量中是否存在逗号来对观察结果进行子集化。对于包含逗号的观察结果,我然后使用 strsplit 来分隔数字。然后,我计算每个观察值存在多少个数字,并以此复制每个观察值。然后,我将分割的数字融合到一个数据框中,其中所有数字都位于名为“value”的变量中。然后,我只需将“alpha”变量替换为熔化的“value”变量中的数据。然后我用不包含逗号的数据重新绑定它。然后我使用这个 df 并处理“beta”变量......
这是我的解决方案(似乎有效?):
library(reshape2)
demo$a<-grepl(",", demo$alpha)
demo.atrue <- demo[ which(demo$a=='TRUE'), ]
demo.afalse <- demo[ which(demo$a=='FALSE'), ]
demo.atrue$alpha<-as.character(demo.atrue$alpha)
temp<-strsplit(demo.atrue$alpha, ",")
temp.lengths<-lapply(temp, length)
for (i in 1:length(temp)) {
df.expanded <- demo.atrue[rep(row.names(demo.atrue), temp.lengths), 1:3]
}
temp.melt<-melt(temp)
df.expanded$alpha<-temp.melt$value
demo.afalse<-demo.afalse[c(1:3)]
demonew<-rbind(demo.afalse, df.expanded)
demonew$b<-grepl(",", demonew$beta)
demonew.btrue <- demonew[ which(demonew$b=='TRUE'), ]
demonew.bfalse <- demonew[ which(demonew$b=='FALSE'), ]
demonew.btrue$beta<-as.character(demonew.btrue$beta)
temp<-strsplit(demonew.btrue$beta, ",")
temp.lengths<-lapply(temp, length)
for (i in 1:length(temp)) {
df.expanded1 <- demonew.btrue[rep(row.names(demonew.btrue), temp.lengths), 1:3]
}
temp.melt<-melt(temp)
df.expanded1$beta<-temp.melt$value
demonew.bfalse<-demonew.bfalse[c(1:3)]
demonew1<-rbind(df.expanded1, demonew.bfalse)
demonew1 #this seems to work, but doesn't feel very efficient
除了效率可能不高之外,我不确定这是否在所有情况下都有效。特别是如果同一观察的“alpha”和“beta”变量中存在多个数字。我用几个例子测试了它,看起来没问题,但我对此没有信心。
感谢您的考虑。