Ответ франка

то у меня есть:

id<-c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2)
measure<-c("speed","weight","time","speed","weight","time","speed","weight","time",
           "speed","weight","time","speed","weight","time","speed","weight","time")
value<-c(1.23,10.3,33,1.44,10.4,31,1.21,10.1,33,4.25,12.5,38,1.74,10.8,31,3.21,10.3,33)
testdf<-data.frame(id,measure,value) 

Это то, что я хочу:

id<-c(1,1,1,2,2,2)  
speed<-c(1.23,1.44,1.21,4.25,1.74,3.21)
weight<-c(10.3,10.4,10.1,12.5,10.8,10.3)
time<-c(33,31,33,37,31,33)
res<-data.frame(id,speed,weight,time) 

Проблема заключается в том, что мои переменные скорость, вес и время повторяются. Я могу сделать это с помощью цикла for с операторами if, но это большая головная боль и не очень эффективная. Это мой первый пост на stackoverflow ... давний вопрос пользователя в первый раз ... спасибо вам всем!

Ответы на вопрос(5)

С помощьюrowid из data.table (очень похоже на ответ @ Kelli-Jean):

library(reshape2)

testdf$r <- data.table::rowid(testdf$measure); 
dcast(testdf, id + r ~ measure)

  id r speed time weight
1  1 1  1.23   33   10.3
2  1 2  1.44   31   10.4
3  1 3  1.21   33   10.1
4  2 4  4.25   38   12.5
5  2 5  1.74   31   10.8
6  2 6  3.21   33   10.3

Или в одну строкуdcast(testdf, id + data.table::rowid(measure) ~ measure).

Или без data.table, добавить какtestdf$r <- ave(testdf$id, testdf$meas, FUN = seq_along).

Или, если вы готовы изучить пакет data.table:

library(data.table)
setDT(testdf)
testdf[, r := rowid(measure)]
dcast(testdf, id + r ~ measure)
 Wen-Ben08 сент. 2017 г., 22:33
Я смущен предыдущим опубликованным ответом, однако ваш имеет большой смысл!
 Uwe24 сент. 2017 г., 10:26
Почему бы вам не опубликовать полныйdata.table решение:library(data.table); dcast(as.data.table(testdf)[, rn := rowid(measure)], id + rn ~ measure)[, -"rn"] или жеdcast(setDT(testdf), paste(id, rowid(measure), sep = "_") ~ measure) ?
 David Arenburg24 сент. 2017 г., 10:14
Почему вы используете reshape2? Вы пытаетесь сохранить его в формате data.frame?
 Wen-Ben08 сент. 2017 г., 22:40
~ Добавил мой :), спасибо за отличный ответ, уточните этот вопрос

Если вы хотите пойти по тидиверсу:

library(tidyr)
library(dplyr)
testdf %>% 
  # add unique id for rows to be able to use spread
  group_by(measure) %>% mutate(unique_id = row_number()) %>% 
  spread(measure, value) %>% select(-unique_id )

Поваренная книга R является отличным ресурсом для таких вопросов:http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/

Затем создайте еще один идентификатор, чтобы упорядочить данные по трем последовательным строкам за раз, как у вас в нужном наборе данных.

A<-c("A","A","A")
B<-c("B","B","B")
C<-c("C","C","C")
D<-c("D","D","D")
E<-c("E","E","E")
F<-c("F","F","F")

A <- as.data.frame(A)
colnames(A) <- "id2"
B <- as.data.frame(B)
colnames(B) <- "id2"
C <- as.data.frame(C)
colnames(C) <- "id2"
D <- as.data.frame(D)
colnames(D) <- "id2"
E <- as.data.frame(E)
colnames(E) <- "id2"
F <- as.data.frame(F)
colnames(F) <- "id2"

Свяжите отдельные наборы данных вместе по ряду

x<-rbind(A,B,C,D,E,F)

Привязать этот новый идентификатор к столбцу testdf целесообразно

testdf <- cbind(testdf, x)

Форма данных от длинного до широкого формата

x2<-dcast(testdf, id + id2 ~ measure, value.var="value")

Это результирующий набор данных:

  id id2 speed time weight
1  1   A  1.23   33   10.3
2  1   B  1.44   31   10.4
3  1   C  1.21   33   10.1
4  2   D  4.25   38   12.5
5  2   E  1.74   31   10.8
6  2   F  3.21   33   10.3

Вы можете удалить переменную id2, если это необходимо, используя

 testdf$id2 <- NULL

Вот мое решение

library(plyr)

a=daply(testdf, .(id, measure), function(x) x$value)
listdf=apply(a, c(3), function(x) rbind(data.frame(x,id=row.names(x))))
df <- ldply(listdf, data.frame)
df$.id=NULL
df <- df[order(df$id),] 
df

  speed time weight id
1  1.23   33   10.3  1
3  1.44   31   10.4  1
5  1.21   33   10.1  1
2  4.25   38   12.5  2
4  1.74   31   10.8  2
6  3.21   33   10.3  2

ОБНОВЛЕНИЕ: Оригинальный ответ от @Frank:

> library(reshape2)
> testdf$r <- data.table::rowid(testdf$measure); 
> dcast(testdf, id + r ~ measure)

  id speed weight time
1  1  1.23   10.3   33
2  1  1.44   10.4   31
3  1  1.21   10.1   33
4  2  4.25   12.5   37
5  2  1.74   10.8   31
6  2  3.21   10.3   33
 Wen-Ben08 сент. 2017 г., 21:27
Можете ли вы объяснить, как с помощью расплава достичь этого?
 Sagar11 сент. 2017 г., 15:14
Да. Я думаю, что я пробовал что-то еще здесь. Я обновлю решение.
 Frank08 сент. 2017 г., 22:51
Я думаю, что вы неправильно поняли вопрос и показываете, как действовать в обратном направлении.
 Wen-Ben08 сент. 2017 г., 22:07
Ошибка: переменные id не найдены в данных: скорость, вес, время
 Uwe24 сент. 2017 г., 10:04
Этот пост является просто копиейОтвет франка.

Ваш ответ на вопрос