在R中扩展csv数据

在R中扩展csv数据,r,excel,csv,reshape,R,Excel,Csv,Reshape,我有以下列标题的数据: Sheet Number, Year, Term, Class, Debate #, Role in Debate, Gender of Evaluator, Person #1 Clarity, Person #1 Effort, Person #1 Gender, Person #1 Origin, Debater Number, Person #2 Clarity, Person #2 Effort, Person #2 Gender, Person #2

我有以下列标题的数据:

Sheet Number, Year, Term, Class, Debate #, Role in Debate, Gender of Evaluator, Person #1 Clarity, Person #1 Effort, Person #1 Gender,  Person #1 Origin, Debater Number, Person #2 Clarity, Person #2 Effort, Person #2 Gender,    Person #2 Origin, Debater Number, Person #3 Clarity, Person #3 Effort, Person #3 Gender, Person #3 Origin, Debater Number, Person #4 Clarity, Person #4 Effort, Person #4 Gender, Person #4 Origin, Debater Number, Person #5 Clarity, Person #5 Effort, Person #5 Gender, Person #5 Origin, Debater Number, Person #6 Clarity, Person #6 Effort, Person #6 Gender, Person #6 Origin, Debater Number, Person #7 Clarity, Person #7 Effort, Person #7 Gender, Person #7 Origin, Debater Number, Person #8 Clarity, Person #8 Effort, Person #8 Gender, Person #8 Origin, Debater Number, Learned from Team 1, Learned from Team 2, Who won?, Sheet all 10s?, Evaluator Class Year
Sheet Number, Year, Term, Class, Debate #, Gender of Evaluator, Evaluator Class Year, Role in Debate, Debate Team Member #, Debater Number, Gender of Debate Team Member, Origin of Debate Team Member, Clarity of Debate Team Member, Effort of Debate Team Member, Learned from Team 1, Learned from Team 2, Who won?, Sheet all 10s?, =1 if Gender of Evaluator==Gender of Debater
我想将其转换为具有以下列标题的格式:

Sheet Number, Year, Term, Class, Debate #, Role in Debate, Gender of Evaluator, Person #1 Clarity, Person #1 Effort, Person #1 Gender,  Person #1 Origin, Debater Number, Person #2 Clarity, Person #2 Effort, Person #2 Gender,    Person #2 Origin, Debater Number, Person #3 Clarity, Person #3 Effort, Person #3 Gender, Person #3 Origin, Debater Number, Person #4 Clarity, Person #4 Effort, Person #4 Gender, Person #4 Origin, Debater Number, Person #5 Clarity, Person #5 Effort, Person #5 Gender, Person #5 Origin, Debater Number, Person #6 Clarity, Person #6 Effort, Person #6 Gender, Person #6 Origin, Debater Number, Person #7 Clarity, Person #7 Effort, Person #7 Gender, Person #7 Origin, Debater Number, Person #8 Clarity, Person #8 Effort, Person #8 Gender, Person #8 Origin, Debater Number, Learned from Team 1, Learned from Team 2, Who won?, Sheet all 10s?, Evaluator Class Year
Sheet Number, Year, Term, Class, Debate #, Gender of Evaluator, Evaluator Class Year, Role in Debate, Debate Team Member #, Debater Number, Gender of Debate Team Member, Origin of Debate Team Member, Clarity of Debate Team Member, Effort of Debate Team Member, Learned from Team 1, Learned from Team 2, Who won?, Sheet all 10s?, =1 if Gender of Evaluator==Gender of Debater
两者之间的主要区别在于,在第一种格式中,每个页码都有5-8个编号的“人员”。第二种格式是,每个图纸编号都有一个人与其关联,因此每个图纸编号都会出现多次,并且数据会展开


我怎样才能在R中实现这一点?我一直在尝试使用“重塑”软件包。谢谢

我借此机会了解了一点tidyr,我很高兴我了解了

正如@JamesKing所建议的,您提供的不是最好的MWE,因此我创建了一些具有类似结构的数据。我认为这一切都适用于你的例子,尽管如此,通过一些解释,你应该能够将其转化为你的数据。话虽如此,由于您似乎是从Excel电子表格开始的,因此提出一种简化数据收集和分离的命名约定将是有益的

我的数据:

set.seed(1)
n <- 5
dat <- data.frame(
  sheetNum = 1:n,
  year = sample(2000:2025, size = n),
  roleInDebate = sample(letters, size = n, replace = TRUE),
  Clarity.1 = sample(10, size = n, replace = TRUE),
  Effort.1 = sample(10, size = n, replace = TRUE),
  Clarity.2 = sample(10, size = n, replace = TRUE),
  Effort.2 = sample(10, size = n, replace = TRUE),
  Clarity.3 = sample(10, size = n, replace = TRUE),
  Effort.3 = sample(10, size = n, replace = TRUE))
dat
#   sheetNum year roleInDebate Clarity.1 Effort.1 Clarity.2 Effort.2 Clarity.3
# 1        1 2006            x         3        5        10        4         5
# 2        2 2009            y         2        8         3        1         6
# 3        3 2013            r         7       10         7        4         5
# 4        4 2020            q         4        4         2        9         2
# 5        5 2004            b         8        8         3        4         9
分解它 要了解发生了什么,让我们逐步了解一下。“聚集”步骤只是将未提及的列组合成一对键/值列,如下所示:

dat %>% gather(var, val, -sheetNum, -year, -roleInDebate) %>% head()
#   sheetNum year roleInDebate       var val
# 1        1 2006            x Clarity.1   3
# 2        2 2009            y Clarity.1   2
# 3        3 2013            r Clarity.1   7
# 4        4 2020            q Clarity.1   4
# 5        5 2004            b Clarity.1   8
# 6        1 2006            x  Effort.1   5
请注意,我所包含的列是如何以-开头的,并保持逐字逐句。接下来,我们需要拆分或分离var列:

这里发生的事情不多,但对于下一步来说非常重要:扩展数据,或者使用skill和val从不同的键/值列对中传播数据,这将创建名为Clarity和efforce的新列,正如我们在上面的解决方案中所看到的

希望这有帮助


顺便说一句:对于一个好的MWE,通常建议提供来自dputdat的输出,其中dat是一个小但有代表性的数据结构,有助于我们理解起点和您的预期输出。这里,一个小的数据帧将是合适的。

< P>假设@ R2EvsS的示例数据有点代表您的问题,这里有几个其他的选项要考虑。 选项1:基础R的重塑

奇怪的是,在重塑工具方面,以您描述的重塑任务命名的函数似乎是害群之马。如果它是你的常规工具包的一部分,那么掌握窍门并不难

对于此问题,一种方法可能是:

reshape(dat, direction = "long", idvar = 1:3, varying = 4:ncol(dat), sep = ".")
我对重塑的关注不是它的语法,而是1它不能处理不平衡的宽到长转换,例如,如果你有3个Clarity列,但只有2个Work列,2当你开始处理很多行或很多列需要重塑时,它的速度会非常慢。因此,我编写了merged.stack

选项2:merged.stack

我编写了merged.stack作为splitstackshape包的一部分,以处理与重塑、方向=长、。。。例如,与重塑/重塑2的熔化和tidyr随后的聚集不同。我还想通过识别变量存根来简化选择感兴趣的变量的过程,在这种情况下,清晰和努力

如前所述,merged.stack的设计也很快

library(splitstackshape)
merged.stack(dat, var.stubs = c("Clarity", "Effort"), sep = ".")
#     sheetNum year roleInDebate .time_1 Clarity Effort
#  1:        1 2006            x       1       3      5
#  2:        1 2006            x       2      10      4
#  3:        1 2006            x       3       5      7
#  4:        2 2009            y       1       2      8
#  5:        2 2009            y       2       3      1
#  6:        2 2009            y       3       6      8
#  7:        3 2013            r       1       7     10
#  8:        3 2013            r       2       7      4
#  9:        3 2013            r       3       5      2
# 10:        4 2020            q       1       4      4
# 11:        4 2020            q       2       2      9
# 12:        4 2020            q       3       2      8
# 13:        5 2004            b       1       8      8
# 14:        5 2004            b       2       3      4
# 15:        5 2004            b       3       9      5
选项3:等待data.table版本1.9.8中的熔化

嗯。嗯,这可能不是一个真正的选项,但是data.table开发人员工作得很快,所以谁知道呢,但是在data.table的1.9.8版本中,您将能够熔化指定的列列表。或者,如果您更喜欢冒险,请立即安装并试用:-

最终,这可能会使merged.stack变得多余,因为它将具有类似的功能,但从我所做的一些试验中可以看出,它的速度更快

更新-基准 我在下面测试了merged.stack和@r2evan的方法。我没有测试重塑,因为我担心它会使我的系统缓慢爬行。我没有从data.table测试熔体,因为最好等待生产发布

以下是一些示例数据:

set.seed(1)
n <- 100000
r <- 6
dat <- data.frame(
  sheetNum = 1:n,
  year = sample(2000:2025, size = n, TRUE),
  roleInDebate = sample(letters, size = n, replace = TRUE),
  matrix(sample(10, n * r * 2, TRUE), nrow = n, 
         dimnames = list(NULL, paste(c("Clarity", "Effort"), 
                                     rep(seq_len(r), each = 2), 
                                     sep = "."))))
并验证输出是否相同:

out1 <- r2evans()
out2 <- ananda()

library(compare)
compare(out1, out2, allowAll = TRUE)
# TRUE
#   renamed
#   dropped names
#   dropped attributes

欢迎来到StackOverflow!特别是对于这类数据的宽度,我敦促您做出一个正确的选择。在这种情况下,将问题概括到少数几个专栏中,在这些专栏中,您可以在不淹没我们的情况下获得概念。此外,提供具有代表性的数据结构非常有帮助。因此,原始格式看起来像页码、1人清晰度、1人努力程度、1人性别、1人出身、辩论者编号、2人清晰度、2人努力程度、2人性别、2人出身、辩论者编号、3人清晰度、3人努力程度,第三个人的性别,第三个人的出身,辩论者的编号,我希望它是类似于表号,辩论团队成员,辩论者编号,辩论团队成员的性别,辩论团队成员的出身,辩论团队成员的清晰性,辩论团队成员的努力,即每个页码仅与一个人相关,这不是一个可重复的最小示例。我建议
谢谢你:1。制作一个小数据集。2.发布针对数据集运行的R代码及其生成的内容。3.你期望它产生什么。那么我们就可以帮助你了。回答得很好+谢谢你。种子@AnandaMahto@r2evans,我看到了眨眼,但仅供参考,这不是真正的炫耀,特别是因为我真的认为Arun在melt for data.table上所做的工作会使我的功能变得多余。使用类似于dpyr+tidyr的重塑2工具的标准方法是将所有内容粉碎成一个细长的数据集,然后忽略列类型,从那里重塑,然后将它们重新扩展到广泛的形式。这似乎没有必要。merged.stack试图避免这种情况,melt的data.table实现也是如此。对于更大的数据集来说,这可能是一个巨大的问题。要理解我忽略列类型的意思,请看一次熔化多个列类型的地方。spread求助于使用type.convert,这也会增加处理时间。我还在cSplit中使用type.convert,并在splitstackshape中使用相关函数。这一点值得注意,但我既不参与竞争,也不认为这一特定问题与性能有关,更重要的是简化了存储在人工维护的电子表格中的数据。我通常更喜欢性能高效的代码,并且没有充分使用这两个包中的任何一个来感受性能的冲击。谢谢你的指点,这是一个很好的提醒,优雅并不总是更快,基地已经被审查相当好的速度。
library(microbenchmark)
microbenchmark(r2evans(), ananda(), times = 10)
# Unit: milliseconds
#       expr       min        lq      mean    median        uq       max neval
#  r2evans() 3514.0961 3603.7102 3839.6097 3713.6705 3959.5320 4380.4601    10
#   ananda()  320.5602  336.2396  363.7165  367.3344  386.3064  417.7994    10
out1 <- r2evans()
out2 <- ananda()

library(compare)
compare(out1, out2, allowAll = TRUE)
# TRUE
#   renamed
#   dropped names
#   dropped attributes