2017-11-17 10 views
-1

데이터베이스에 벡터를 만드는 함수를 정의하는 데 도움이 필요합니다. 각 행에 대해 함수는 해당 데이터베이스의 다른 열을 살펴보고 지정된 값에서 해당 값을 검색합니다 열을 검색하고, 일치하는 모든 행으로 구성된 해당 두 번째 데이터베이스의 서브 세트를 작성하고, 새 서브 세트의 개별 컬럼을 합한 다음, 해당 값을 원래 데이터베이스의 새 컬럼의 해당 행에 리턴합니다. 즉사용자 정의 함수 R 하위 집합을 만들고 합산하기위한 함수

,이 같은 모습 데이터 프레임이 있습니다

X <- as.character(unique(df$ID)) 
> X 
[1] "a" "b" "c" "d" "e" 

:

ID <- c('a', 'b', 'c', 'd', 'e') 
M <- 20:39 
df <- data.frame(cbind(ID, M)) 
df$M <- as.numeric(df$M) 
> df 
    ID M 
1 a 1 
2 b 2 
3 c 3 
4 d 4 
5 e 5 
6 a 6 
7 b 7 
8 c 8 
9 d 9 
10 e 10 
11 a 11 
12 b 12 
13 c 13 
14 d 14 
15 e 15 
16 a 16 
17 b 17 
18 c 18 
19 d 19 
20 e 20 
> str(df) 
'data.frame': 20 obs. of 2 variables: 
$ ID: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5 1 2 3 4 5 ... 
$ M : num 1 2 3 4 5 6 7 8 9 10 ... 

내가 새로운 데이터 프레임, Z를 만들 싶습니다을 같은 Z <- data.frame(cbind(X, Y))Y은 모든 a의 합, 모든 b의 합, 모든 c의 합 등의 벡터입니다.

따라서 Y sh c(34, 38, 42, 46, 50)에 동일하고 울드 내 최종 결과가 있어야한다 :

> Z 
    X Y 
1 a 34 
2 b 38 
3 c 42 
4 d 46 
5 e 50 
> str(Z) 
'data.frame': 5 obs. of 2 variables: 
$ X: chr "a" "b" "c" "d" ... 
$ Y: num 34 38 42 46 50 

이 작업을 수행하려면, 내가 먼저 데이터 프레임에 X 터닝 시도했습니다 (이 데이터 테이블로 작업하기 쉽다?) :

> Z <- data.frame(X) 
> Z 
    X 
1 a 
2 b 
3 c 
4 d 
5 e 
> str(Z) 
'data.frame': 5 obs. of 1 variable: 
$ X: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5 

다음 Z$Y <- sum(df[df$ID == Z$X, 2])Y을 정의하지만 고유 값하지 않습니다 나는 또한 시도했다

> Z 
    X Y 
1 a 210 
2 b 210 
3 c 210 
4 d 210 
5 e 210 

함수정의를과 같이 :

f1 <- function(v, w, x, y, z){sum(v[v$w == x$y, z])} 

하지만 그 날을 가져옵니다

f1 <- function(df, cols, match_with, to_x = 50){ 
    df[cols] <- lapply(df[cols], function(i) 
    ifelse(grepl(to_x, match_with, fixed = TRUE), 'MID', 
      i)) 
    return(df) 
} 

이것은 찾습니다

> f1(df, 'ID', Z, 'X', 'M') 
[1] 0 

나는 비슷한 무언가를이 포럼에 다른 포스트에서 함수를 발견했다 match_with 열에서 "50"값을 가져오고 cols으로 지정된 열의 해당 행에 "MID"값을 반환하며 동일한 지정된 데이터 기준 e df. 그래서 to_x = 50을 고정 값 "50"대신에 Z$X에있는 값을 찾고 고정 값 "MID"를 반환하는 대신 값의 합을 반환하는 것으로 바꾸어야합니다. df[df$ID == Z$X, df$M]. 나는 다음의 변화를 작성하여 이러한 변경에게 자신을 시도했습니다

f1 <- function(df, cols, match_with, to_x = df[ , 1], x){ 
    df[cols] <- lapply(df[cols], function(i) 
    ifelse(grepl(to_x, match_with, fixed = TRUE), sum(x), 
      i)) 
    return(df) 
} 

하지만, 지금까지, 내 ​​변화의 어느 것도 생성되지 않은 원하는 결과를. 이 사람은 내게 준 :

> f1(Z, df, cols = c('Y'), match_with = df$ID, x = df$M) 
    X Y 
1 a 210 
2 b 210 
3 c 210 
4 d 210 
5 e 210 
Warning messages: 
1: In grepl(to_x, match_with, fixed = TRUE) : 
    argument 'pattern' has length > 1 and only the first element will be used 
2: In `[<-.data.frame`(`*tmp*`, cols, value = list(Y = c(210, 210, : 
    replacement element 1 has 20 rows to replace 5 rows 

그것은 대신 하위 집합 df$ID == Z$Xdf$M의 전체를 합산 것으로 보인다. 다른 변형에서는 두 번째 데이터 프레임의 열을 참조하는 데 문제가있는 것으로 보입니다.

저는 R에 다소 익숙하며 사용자 정의 함수 작성 경험이 거의 없습니다 (이 질문에서 알 수있는 것처럼).어떤 도움이라도 대단히 감사하게 될 것입니다!

답변

0

신경 쓰지 마라. 나는 그것을 얻었다 고 생각한다!

> f1 <- function(col1, col2, df2, to_add){ 
+ lapply(col1, function(i){ 
+ df2$x <- grepl(i, col2, fixed = TRUE) 
+ df3 <- df2[df2$x == TRUE, to_add] 
+ sum(df3, na.rm = TRUE) 
+ })} 
> Z$Y <- f1(Z$X, df$ID, df, c('M')) 
> Z 
    X Y 
1 a 34 
2 b 38 
3 c 42 
4 d 46 
5 e 50