Простая функция не работает для dcast - reshape2

Предположим, у меня есть эти данные:

 c1 c2 c3
 A  A  AA
 A  B  BB
 A  C  CC
 B  A  DD
 B  B  EE
 B  C  FF
 C  A  GG
 C  B  HH
 C  C  II
 A  A  JJ

Я хочу изменить их с помощью dcast с помощью этой функции:

dcast(data,c1~c2,value.var="c3",function(x)x)

Но я получаю эту ошибку:

Error in vapply(indices, fun, .default) : values must be length 0,
 but FUN(X[[1]]) result is length 1

Как можно использовать новую функцию с dcast (функция, определяемая пользователем).

Я хочу получить:

  A   B   C
A AA BB  CC
B DD EE  FF
C GG HH  II
A JJ NA  NA

person user1436187    schedule 04.08.2015    source источник
comment
Что function(x)x? Каков ваш желаемый результат?   -  person David Arenburg    schedule 04.08.2015
comment
Фиктивная функция для возврата value.var без изменений.   -  person user1436187    schedule 04.08.2015
comment
Только 1_?   -  person David Arenburg    schedule 04.08.2015
comment
Он возвращает длину переменной из-за дублирования строк в моем реальном наборе данных.   -  person user1436187    schedule 04.08.2015
comment
Итак, что вы хотите вернуть, когда есть дубликат?   -  person David Arenburg    schedule 04.08.2015
comment
Поместите некоторые символы, такие как NA.   -  person user1436187    schedule 04.08.2015
comment
Поэтому, пожалуйста, сделайте свой пример воспроизводимым и предоставьте точный желаемый результат.   -  person David Arenburg    schedule 04.08.2015
comment
Разве не должно быть JJ в последней строке?   -  person David Arenburg    schedule 04.08.2015
comment
@ Хенрик Хорошо, я удалил ответ. Счастливый :-)   -  person akrun    schedule 04.08.2015


Ответы (2)


Вот возможное решение с использованием data.tables v 1.9.5+ новой функции rleid, которая создаст индекс для столбца c1 (вы можете удалить indx впоследствии, если хотите)

library(data.table) # v 1.9.5+
dcast(setDT(stocksm)[, indx := rleid(c1)], indx + c1 ~ c2, value.var = "c3")
#    indx c1  A  B  C
# 1:    1  A AA BB CC
# 2:    2  B DD EE FF
# 3:    3  C GG HH II
# 4:    4  A JJ NA NA

### installing the development version
# library(devtools)
# install_github("Rdatatable/data.table", build_vignettes = FALSE)

Таким образом, в основном после создания индекса на c1 мы распространяем данные более или менее, как и раньше, включая indx внутри


Или, если вы настаиваете на tidyr, вот вариант

library(tidyr)
stocksm$indx <- with(rle(as.character(stocksm$c1)), rep(seq_along(lengths), lengths))
spread(stocksm, c2, c3)
#   c1 indx  A    B    C
# 1  A    1 AA   BB   CC
# 2  A    4 JJ <NA> <NA>
# 3  B    2 DD   EE   FF
# 4  C    3 GG   HH   II
person David Arenburg    schedule 04.08.2015
comment
tidyr пакет имеет spread функцию, может ли она дать такой же результат. - person user1436187; 04.08.2015

Другой способ использования dcast — создание уникальных идентификаторов с помощью cumsum. Функция не будет знать, какое значение заполнять для дубликатов, таких как A A, если оно не создано.

data$ids <- cumsum(c(T,diff(as.numeric(data$c1)) != 0L))
dcast(data, ids+c1~c2, value.var="c3")[-1]
#   c1  A    B    C
# 1  A AA   BB   CC
# 2  B DD   EE   FF
# 3  C GG   HH   II
# 4  A JJ <NA> <NA>
person Pierre L    schedule 04.08.2015