2016-06-16 2 views
2

의가 나는 week1_d 열에서 week2_d 열을 만들 수있는 간단한 방법이 있나요이R : 만들기 여러 새로운 열이 다른 열을 기반으로

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a 
    1  12  22  17  4 
    1  15  32  18  5 
    1  24  12  29  6 
    2  45  11  19  8 
    2  23  33  20  10") 

과 같은 데이터 프레임이 등 가정 해 봅시다 매주, week1_t와 week1_a의 차이점을 기반으로합니까? 아니면 "차이"열을 수동으로 만들어야합니까?

예상 출력은 다음과 같습니다 : 실제로

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a week1_d week2_d 
    1  12  22  17  4  10  -13     
    1  15  32  18  5  17  -13 
    1  24  12  29  6  -12  -23 
    2  45  11  19  8  -34  -11 
    2  23  33  20  10  10  -10  ") 

,이 약 30주, 그래서이 일을 수동으로 방지하기 위해 노력하고 있습니다. 나는 매주 반복되는 for 루프를 생각하고 주 + (index of loop)와 일치하는 컬럼을 grepping했다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

5

"관점에서 볼 때 문제는 열 이름에 데이터 (여러 개!)를 인코딩한다는 것입니다. 주 번호와 그 문자의 의미는 무엇이든간에. 내가 주 형식의 긴 형식으로 변환하고 d = a - t을 정의하고 (필요한 경우) 와이드 형식으로 다시 변환합니다. 그러나 아마도 다른 형식의 작업을 계속 진행하고 싶다면 다른 작업을 원한다면 긴 데이터 (조작, 모델링, 플로팅 등)에서 구현하기가 더 쉬워지기 때문일 수 있습니다.

library(tidyr) 
library(dplyr) 

long = dd %>% 
    mutate(real_id = 1:n()) %>% 
    gather(key = key, value = value, starts_with("week")) %>% 
    separate(key, into = c("week", "letter")) %>% 
    spread(key = letter, value = value) %>% 
    mutate(d = a - t) 

head(long) 
# ID real_id week a t d 
# 1 1  1 week1 22 12 10 
# 2 1  1 week2 4 17 -13 
# 3 1  2 week1 32 15 17 
# 4 1  2 week2 5 18 -13 
# 5 1  3 week1 12 24 -12 
# 6 1  3 week2 6 29 -23 

wide = gather(long, key = letter, value = value, a, t, d) %>% 
    mutate(key = paste(week, letter, sep = "_")) %>% 
    select(-week, -letter) %>% 
    spread(key = key, value = value) 

wide 
# ID real_id week1_a week1_d week1_t week2_a week2_d week2_t 
# 1 1  1  22  10  12  4  -13  17 
# 2 1  2  32  17  15  5  -13  18 
# 3 1  3  12  -12  24  6  -23  29 
# 4 2  4  11  -34  45  8  -11  19 
# 5 2  5  33  10  23  10  -10  20 
+0

좋은 답변입니다! 고마워, 그레 거. – Parseltongue

+0

@ 그레고르 대단한 답변 – nik

3

우리는 listsub와 접미사를 제거한 후 데이터 세트의 names으로 '주'열 (dd[-1]를) split, 두 열 사이의 차이를 얻고 'DD'에 새 열을 만들 수 list 요소를 할당 .

lst <- lapply(split.default(dd[-1], 
      sub("_.*", "", names(dd)[-1])), function(x) x[2]-x[1]) 
dd[paste0("week_", seq_along(lst), "d")] <- lapply(lst, unlist, use.names=FALSE) 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 

열 즉 교대 'week2_a'다음 'week1_a'다음 'week2_t'다음 'week1_t'하는 경우에 "단정 데이터 등에서

Un1 <- unique(sub("_.*", "", names(dd)[-1])) 
i1 <- c(TRUE, FALSE) 
dd[paste0(Un1, "_d")] <- dd[-1][!i1]- dd[-1][i1] 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 
+0

@Parseltongue 업데이트되었습니다. 도움이되는지 확인하십시오 – akrun

+0

흠. 코드가하는 일을 정확히 알지 못합니다. 첫 번째 분할 명령의 목적은 무엇입니까? 다음과 같은 오류가 나타납니다. https://i.imgur.com/JDe1qYM.png – Parseltongue

+0

@Parseltongue 이것은 보여준 예를 기반으로합니다. 그것은 나를 위해 작동합니다. BTW, 여기에서는'base R' 함수 만 사용하고 있습니다. – akrun

관련 문제