从宽到长的w /耦合列:是否有更多的R方法(即 - 不使用for循环)?

Ama*_*shy 3 r

我有一个如下所示的数据集:

phrase      wo1sp     wo2sp     wo3sp     wo1sc     wo2sc     wo3sc
hello       dan       mark      todd      10        5         4
hello       mark      dan       chris     8         9         4
goodbye     mark      dan       kev       2         4         10
what        kev       dan       mark      4         5         5
Run Code Online (Sandbox Code Playgroud)

我想把它改成这样的东西:

phrase      sp      sc
hello       dan     10 
hello       mark    5
hello       todd    4
hello       mark    8
hello       dan     9
hello       chris   4
goodbye     mark    2
goodbye     dan     4
goodbye     kev     10
what        kev     4
what        dan     5
what        mark    5
Run Code Online (Sandbox Code Playgroud)

我遇到的许多建议并不依赖于数据列彼此耦合 - 因此建议最终会丢失信息等信息gather.我昨天问了这个问题.

我已经解决了这个问题:

library("tidyverse")

test_set = tribble(~phrase,      ~wo1sp,     ~wo2sp,     ~wo3sp,     ~wo1sc,     ~wo2sc,     ~wo3sc,
                   "hello",       "dan",       "mark",      "todd",      10,        5,         4,
                   "goodbye",     "mark",      "dan",       "kev",       2,         4,         10,
                   "what",        "kev",       "dan",       "mark",      4,         5,         5,
                   "hello",       "mark",      "dan",       "mark",      4,         7,         10)

tmp_list <- list()
for (ii in 1:3) {
  selected_data <- test_set %>%
    group_by(phrase) %>%
    select(matches(paste("wo", ii, "|phrase", sep="")))
  names(selected_data) <- c("phrase", "sp", "sc")
  tmp_list[[ii]] <- selected_data
}
ds <- do.call(rbind, tmp_list)
Run Code Online (Sandbox Code Playgroud)

这给了我我想要的东西,但感觉......哈哈.在R中,我尽可能地避免循环并乱搞列名(直到最后的清理).甚至select声明也很有趣.我相信有一种更清洁的方式可以做到这一点,但我已经花了很长时间(主要是tidyr)试图弄清楚如何,并且没有提出任何建议.

有没有人有任何想法?

(重复的问题似乎是相同的,但这个问题的答案完全不同[并且冷却方式])

tal*_*lat 7

data.table 救援..

library(data.table)
setDT(df)
melt(df, id.vars = "phrase", measure.vars = patterns(sp = "sp$", sc = "sc$"))
 #    phrase variable    sp sc
 #1:   hello        1   dan 10
 #2:   hello        1  mark  8
 #3: goodbye        1  mark  2
 #4:    what        1   kev  4
 #5:   hello        2  mark  5
 #6:   hello        2   dan  9
 #7: goodbye        2   dan  4
 #8:    what        2   dan  5
 #9:   hello        3  todd  4
#10:   hello        3 chris  4
#11: goodbye        3   kev 10
#12:    what        3  mark  5
Run Code Online (Sandbox Code Playgroud)

measure=patterns(sp = "sp$", sc = "sc$")允许您指定遵循命名模式,在这种情况下,所有关联列组sp列结尾sp,并与其他人sc.因此,您将这两列作为输出.该variable列是一个附加信息,可以告诉您数据来自哪个列组的原始列.