2016-10-06 3 views
0

다음 샘플 data.frame :용융 4 열 두 변수 열을 결합하면서

Date <- seq(as.Date("2016/9/1"), as.Date("2016/9/10"), "days") 
A <- sample(0:200, 10) 
B <- sample(0:400, 10) 
A_limit <- rep(200,10) 
B_limit <- rep(400,10) 
data_sample <- data.frame(Date,A,B,A_limit,B_limit) 

>  Date A B A_limit B_limit 
1 2016-09-01 175 270  200  400 
2 2016-09-02 160 50  200  400 
3 2016-09-03 173 25  200  400 
... 

나는 형태로 모양을 변경하고 싶습니다 :

>  Date limit variable value 
1 2016-09-01 200  A 175 
2 2016-09-02 200  A 160 
3 2016-09-03 200  A 173 
... 
31 2016-09-01 400  B 270 
32 2016-09-02 400  B 50 
33 2016-09-03 400  B 25 
.... 

내가 얻을 관리 그것은 수행하지만 내 방식은 복잡한에 멀리 나에게 보인다

library("reshape2") 
data_sample_2 <- data_sample %>% melt(id=c("Date","A","B")) 

levels(data_sample_2$variable) <- c(levels(data_sample_2$variable),"A","B") 
data_sample_2$variable[data_sample_2$variable == "A_limit"] <- as.factor("A") 
data_sample_2$variable[data_sample_2$variable == "B_limit"] <- as.factor("B") 

names(data_sample_2)[names(data_sample_2) == "value"] <- "limit" 
names(data_sample_2)[names(data_sample_2) == "variable"] <- "variable_1" 

data_sample_3 <- data_sample_2 %>% melt(id=c("Date","variable_1","limit")) 
data_sample_3 <- droplevels(data_sample_3) 
data_sample_4 <- data_sample_3[data_sample_3$variable_1 == data_sample_3$variable,] 

data_sample_4$variable_1 <- NULL 

가 난 그냥 reshape2 패키지를 사용하기 시작 그러니이 데이터. 프레임 변환을 향상시킬 수있는 방법에 대해 알려주십시오 (아무리 명백해 보이더라도).

+1

'col1 <-c ("A_limit", "B_limit"); col2 <- c ("A", "B")'; 숫자'variable' 칼이 마음에 들지 않는다면, data.table :: melt (data_sample, measure = list (col1, col2), value.name = c ("limit", "value"))' – mtoto

+0

나는 당신의 코드를 시도 할 때이 오류가 발생한다 :'오류 : 데이터에서 측정 값 변수를 찾을 수 없다 : c ("A_limit", "B_limit"), c ("A", "B")'. 무슨 단서가 잘못 됐니? – RandomDude

+1

'data_sample'을'data.table'으로 변환하십시오. – mtoto

답변

1

당신은 (더 그것을 처리하는 방법을보고, 단순히 모든 것을 보내고 stack하여 기본 R을 통해 즉

df1 <- data.frame(Date = data_sample$Date, limit = stack(data_sample[-(1:3)])[[1]], 
        variable = stack(data_sample[2:3])[[2]], 
        value = stack(data_sample[2:3])[[1]], 
            stringsAsFactors = FALSE) 

head(df1) 
#  Date limit variable value 
#1 2016-09-01 200 A  67 
#2 2016-09-02 200 A  100 
#3 2016-09-03 200 A  166 
#4 2016-09-04 200 A  116 
#5 2016-09-05 200 A  89 
#6 2016-09-06 200 A  138 

tail(df1) 
#   Date limit variable value 
#15 2016-09-05 400 B  208 
#16 2016-09-06 400 B  387 
#17 2016-09-07 400 B  125 
#18 2016-09-08 400 B  116 
#19 2016-09-09 400 B  120 
#20 2016-09-10 400 B  241 
+0

나는 그 해결책을 좋아합니다! 스태킹 중에 열의 이름을 직접 지정할 수있는 방법이 있습니까? – RandomDude

+0

@RandomDude updated – Sotos

+1

벡터를 선택할 때 이중 ['[...]]'을 놓쳤습니다. 대단히 감사합니다. – RandomDude

1

이게 원하는가요?

data_sample_2 <- melt(data_sample,id.vars=c("Date","A_limit","B_limit")) 
data_sample_2$limit<- ifelse(data_sample_2$variable=="A",data_sample_2$A_limit,data_sample_2$B_limit) 
data_sample_2[,c("Date","limit","variable","value")] 
1

당신이 당신의 예에서 reshape2을 사용하기 때문에, 그것은 당신이 관심을 가질만한을 수행 할 수 있습니다 업데이트 됨) tidyverse 설정.

나는 당신의 생성 코드를 반복합니다 :

Date <- seq(as.Date("2016/9/1"), as.Date("2016/9/10"), "days") 
A <- sample(0:200, 10) 
B <- sample(0:400, 10) 
A_limit <- rep(200,10) 
B_limit <- rep(400,10) 
data_sample <- data.frame(Date,A,B,A_limit,B_limit) 

# Preview 
head(data_sample) 
#>   Date A B A_limit B_limit 
#> 1 2016-09-01 39 53  200  400 
#> 2 2016-09-02 96 193  200  400 
#> 3 2016-09-03 143 75  200  400 
#> 4 2016-09-04 60 241  200  400 
#> 5 2016-09-05 126 225  200  400 
#> 6 2016-09-06 184 349  200  400 

지금 우리가 "명확한"방식으로 데이터를 조작 ( reshape2가 가지고있는 책임의 정도에 걸릴) dplyrtidyr를 사용할 수 있습니다.

library(dplyr) 
library(tidyr) 

data_clean <- data_sample %>% 
    gather(variable, value, A, B) %>% 
    mutate(limit = if_else(variable == "A", A_limit, B_limit)) %>% 
    select(Date, limit, variable, value) 

# Inspect results 
head(data_clean) 
#>   Date limit variable value 
#> 1 2016-09-01 200  A 39 
#> 2 2016-09-02 200  A 96 
#> 3 2016-09-03 200  A 143 
#> 4 2016-09-04 200  A 60 
#> 5 2016-09-05 200  A 126 
#> 6 2016-09-06 200  A 184 
관련 문제