Рассмотрим следующий набор данных, который взят из этого вопроса: Переход от широких к длинным с соединенными столбцами: есть ли более 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))