Осмысление функции reshape () - PullRequest
0 голосов
/ 08 января 2019

Рассмотрим следующий набор данных, который взят из этого вопроса: Переход от широких к длинным с соединенными столбцами: есть ли более R способ сделать это (т.е. - без использования цикла for)?

(dput в конце вопроса)

   phrase wo1sp wo2sp wo3sp wo1sc wo2sc wo3sc
1   hello   dan  mark  todd    10     5     4
2   hello  mark   dan chris     8     9     4
3 goodbye  mark   dan   kev     2     4    10
4    what   kev   dan  mark     4     5     5

Цель состоит в том, чтобы изменить данные с широких на длинные с учетом того, что в именах столбцов есть некоторый шаблон. Ожидаемый результат -

    phrase time    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

@ docendodiscimus предоставил звуковое решение, используя melt из data.table, но я бы хотел использовать reshape() из библиотеки stats для практики.

Эта функция, безусловно, довольно мощная, но я почти всегда сталкиваюсь с проблемой с одним из ее аргументов, поэтому на этот раз это аргумент new.row.names, который я редко использовал раньше.

Я пытался

reshape(
  dat,
  idvar = "phrase",
  varying = list(
    "sp" = grep("sp$", names(dat)), 
    "sc" = grep("sc$", names(dat))
  ),
  direction = "long", 
  v.names = c("sp", "sc") # name of cols in long format
)

Это возвращает ошибку

ошибка в row.names<-.data.frame (*tmp*, значение = вставка (идентификаторы, времена [i],: дубликаты 'row.names' не допускаются

Дополнительно: предупреждающее сообщение: неуникальное значение при установке 'row.names': ‘hello.1’

Читая сообщение об ошибке, я обнаружил, что «решением» является аргумент new.row.names, который я установил равным 1:12, см. Ниже. (Я обманул здесь, потому что посмотрел, сколько строк было возвращено решением data.table.)

Мой вопрос: каково общее решение этой проблемы?

# works!
reshape(
  dat,
  idvar = "phrase",
  varying = list(
    "sp" = grep("sp$", names(dat)),
    "sc" = grep("sc$", names(dat))
  ),
  direction = "long", 
  v.names = c("sp", "sc"),
  new.row.names = 1:12 # 1:10000 would also work
)

данные

dat <- structure(list(phrase = c("hello", "hello", "goodbye", "what"
), wo1sp = c("dan", "mark", "mark", "kev"), wo2sp = c("mark", 
"dan", "dan", "dan"), wo3sp = c("todd", "chris", "kev", "mark"
), wo1sc = c(10L, 8L, 2L, 4L), wo2sc = c(5L, 9L, 4L, 5L), wo3sc = c(4L, 
4L, 10L, 5L)), .Names = c("phrase", "wo1sp", "wo2sp", "wo3sp", 
"wo1sc", "wo2sc", "wo3sc"), class = "data.frame", row.names = c(NA, 
-4L))
...