2017-12-04 12 views
1

저는 R과 프로그래밍에 새로운 것이 일반적입니다. 나는 현재 데이터 변환을위한 코드 조각을 쓰고 있는데, 누군가 나를 도와 줄 시간을 좀 갖기를 희망한다. 재현 exemple 이하팩터 수준에 따라 변수 계산

:

# Data 
a <- c(rnorm(12, 20)) 
b <- c(rnorm(12, 25)) 
f1 <- rep(c("X","Y","Z"), each=4) #family 
f2 <- rep(x = c(0,1,50,100), 3) #reference and test levels 

dt <- data.frame(f1=factor(f1), f2=factor(f2), a,b) 

#library loading 
library(tidyverse) 

목표 : 계산의 기준 값을 이용하여 모든 값 (a, b). 계산은 a/a_refa_ref = a 인 경우 가족에 따라 f2=0 (f1은 X, Y 또는 Z 일 수 있음)이어야합니다.

은이 코드를 사용하여이 문제를 해결하려 :

test <- filter(dt, f2!=0) %>% group_by(f1) %>% 
    mutate("a/a_ref"=a/(filter(dt, f2==0) %>% group_by(f1) %>% distinct(a) %>% pull)) 

내가 얻을 :

test results

당신이 aa_ref으로 나누어 볼 수있다. 하지만 내 스크립트는 가족 f1에 관계없이 참조 값 (a_ref)의 사용을 재활용하는 것으로 보입니다.

A이 (f1)과 관련하여 계산되었으므로 제안 사항이 있습니까?

읽어 주셔서 감사합니다.


편집

내가 '수동으로 실시'할 수있는 방법을 발견

filter(dt, f1=="X") %>% mutate("a/a_ref"=a/(filter(dt, f1=="X" & f2==0) %>% distinct(a) %>% pull())) 
     f1 f2  a  b   a/a_ref 
    1 X 0 21.77605 24.53115 1.0000000 
    2 X 1 20.17327 24.02512 0.9263973 
    3 X 50 19.81482 25.58103 0.9099366 
    4 X 100 19.90205 24.66322 0.9139422 

문제는 내가 따라서 각 변수와 가족과의 코드를 업데이트해야 할 것이다 그것을하는 깨끗한 방법이 아닙니다.

답변

1
# use this to reproduce the same dataset and results 
set.seed(5) 

# Data 
a <- c(rnorm(12, 20)) 
b <- c(rnorm(12, 25)) 
f1 <- rep(c("X","Y","Z"), each=4) #family 
f2 <- rep(x = c(0,1,50,100), 3) #reference and test levels 

dt <- data.frame(f1=factor(f1), f2=factor(f2), a,b) 

#library loading 
library(tidyverse) 

dt %>% 
    group_by(f1) %>%     # for each f1 value 
    mutate(a_ref = a[f2 == 0],  # get the a_ref and add it in each row 
     "a/a_ref" = a/a_ref) %>% # divide a and a_ref 
    ungroup() %>%     # forget the grouping 
    filter(f2 != 0)     # remove rows where f2 == 0 

# # A tibble: 9 x 6 
#  f1  f2  a  b a_ref `a/a_ref` 
# <fctr> <fctr> <dbl> <dbl> <dbl>  <dbl> 
# 1  X  1 21.38436 24.84247 19.15914 1.1161437 
# 2  X  50 18.74451 23.92824 19.15914 0.9783583 
# 3  X 100 20.07014 24.86101 19.15914 1.0475490 
# 4  Y  1 19.39709 22.81603 21.71144 0.8934042 
# 5  Y  50 19.52783 25.24082 21.71144 0.8994260 
# 6  Y 100 19.36463 24.74064 21.71144 0.8919090 
# 7  Z  1 20.13811 25.94187 19.71423 1.0215013 
# 8  Z  50 21.22763 26.46796 19.71423 1.0767671 
# 9  Z 100 19.19822 25.70676 19.71423 0.9738257 

당신은 사용하여 둘 이상의 변수에 대해이 작업을 수행 할 수 있습니다

일반적으로
dt %>% 
    group_by(f1) %>% 
    mutate_at(vars(a:b), funs(./.[f2 == 0])) %>% 
    ungroup() 

또는은 그들이 당신의 데이터 세트의 다른 후 하나로서 az 사이의 모든 변수를 사용하는 vars(a:z)를 사용합니다.

또 다른 해결책은 같은 mutate_if을 사용할 수 있습니다 : 함수가 당신이 가진 모든 숫자 변수에 적용됩니다

dt %>% 
    group_by(f1) %>% 
    mutate_if(is.numeric, funs(./.[f2 == 0])) %>% 
    ungroup() 

. 변수 f1f2은 요인 변수이므로 해당 변수는 제외됩니다.

+0

'a_ref' 열을 추가하여 언급 한 내용에 따라 올바른 방식으로 계산했는지 확인했습니다. 프로세스가 올바르게 보이면 제거 할 수 있습니다. – AntoniosK

+0

참조 값을 참조하는 새 변수를 만드는 것에 대해 생각하지 않았습니다! 고마워요. 어떤 아이디어 어떻게 모든 값 (a & b)을 계산할 수 있습니까? 실제로 40 개의 변수가 있습니다 ... –

+0

a_ref, b_ref ​​등을 사용 하시겠습니까? – AntoniosK