2011-11-21 2 views
48

루프를 사용하지 않고 데이터 프레임의 값을 조건부로 바꾸는 방법을 이해하려고합니다. 다음과 같이 내 데이터 프레임 구조는 다음과 같습니다data.frame에서 값의 조건부 대체

> df 
      a b est 
1 11.77000 2 0 
2 10.90000 3 0 
3 10.32000 2 0 
4 10.96000 0 0 
5 9.90600 0 0 
6 10.70000 0 0 
7 11.43000 1 0 
8 11.41000 2 0 
9 10.48512 4 0 
10 11.19000 0 0 

을하고 dput 출력은 이것이다 : 내가 원하는 무엇

structure(list(a = c(11.77, 10.9, 10.32, 10.96, 9.906, 10.7, 
11.43, 11.41, 10.48512, 11.19), b = c(2, 3, 2, 0, 0, 0, 1, 2, 
4, 0), est = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("a", 
"b", "est"), row.names = c(NA, -10L), class = "data.frame") 

b의 가치를 확인하는 것입니다. b이 0이면 esta의 값으로 설정하고 싶습니다. df$est[df$b == 0] <- 23은 일 때 est의 모든 값을 23으로 설정한다는 것을 알고 있습니다. 내가 이해할 수없는 것은 esta의 값으로 설정하는 방법입니다. 예를 들어 :

Warning message: 
In df$est[df$b == 0] <- (df$a - 5)/2.533 : 
    number of items to replace is not a multiple of replacement length 

차라리 벡터보다, 관련 셀을 전달할 수있는 방법이 있나요 :

df$est[df$b == 0] <- (df$a - 5)/2.533 

다음과 같은 경고를 준다?

답변

53

조건부 df$est를 색인하고 있기 때문에, 당신은 또한 조건부 인덱스 교체 벡터 df$a 필요 : 물론

index <- df$b == 0 
df$est[index] <- (df$a[index] - 5)/2.533 

을 변수 index은 일시적이며, 나는 코드를 만들기 위해 사용 조금 더 읽을 수 있습니다. 당신은 한 번에 기록 할 수 있습니다 :

df$est[df$b == 0] <- (df$a[df$b == 0] - 5)/2.533 

을 더 나은 일기 좋게 들어, within 사용할 수에 관계없이

df <- within(df, est[b==0] <- (a[b==0]-5)/2.533) 

결과를, 어떤 방법을 당신이 선택 :

df 
      a b  est 
1 11.77000 2 0.000000 
2 10.90000 3 0.000000 
3 10.32000 2 0.000000 
4 10.96000 0 2.352941 
5 9.90600 0 1.936834 
6 10.70000 0 2.250296 
7 11.43000 1 0.000000 
8 11.41000 2 0.000000 
9 10.48512 4 0.000000 
10 11.19000 0 2.443743 

다른 사람들이 지적했듯이, 예에서 대안은 ifelse을 사용하는 것입니다. .

11

다음은 한 가지 방법입니다. ifelse은 벡터화되고 b의 0 값에 대한 모든 행을 확인하고 est(a - 5)/2.53으로 바꿉니다.

df <- transform(df, est = ifelse(b == 0, (a - 5)/2.53, est)) 
5
R-inferno 또는 기본 R- 문서에서 왜 df $ *를 사용하는 것이 최선의 방법이 아닌지 설명합니다. "[": "["에 대한 도움말 페이지 :

"인덱싱 기준 [원자 벡터와 유사하며 지정된 요소의 목록을 선택하십시오.] [[및 $ 모두 목록의 단일 요소를 선택하십시오. 차이점은 $는 계산 된 인덱스를 허용하지 않지만 [[. x $ name은 x [[ "name", exact = FALSE]와 동일 함) 또한 부분 일치 동작 [정확한 [ . "

대신 [row,col] 표기법을 사용하는 것이 좋습니다.예 :

Rgames: foo 
     x y z 
    [1,] 1e+00 1 0 
    [2,] 2e+00 2 0 
    [3,] 3e+00 1 0 
    [4,] 4e+00 2 0 
    [5,] 5e+00 1 0 
    [6,] 6e+00 2 0 
    [7,] 7e+00 1 0 
    [8,] 8e+00 2 0 
    [9,] 9e+00 1 0 
    [10,] 1e+01 2 0 
Rgames: foo<-as.data.frame(foo) 

Rgames: foo[foo$y==2,3]<-foo[foo$y==2,1] 
Rgames: foo 
     x y  z 
1 1e+00 1 0e+00 
2 2e+00 2 2e+00 
3 3e+00 1 0e+00 
4 4e+00 2 4e+00 
5 5e+00 1 0e+00 
6 6e+00 2 6e+00 
7 7e+00 1 0e+00 
8 8e+00 2 8e+00 
9 9e+00 1 0e+00 
10 1e+01 2 1e+01 
+0

이 제품은 upvote에 가치가 , 또는'$ '(또는 이상적으로 모두)로 문제를 요약하십시오. – Andrie

+0

+1이 경우에는'$'연산자가 완벽하다고 생각합니다. (또한, 당신의 경고에도 불구하고 당신은'$'를 사용합니다 ...) – Andrie

+0

@Andrie : 예, 그것이 작동하는 곳에서 사용했습니다. (많은 도움이 아닌 :-)). OP는 문제가 발생한 곳에서 어떤 요소가 작동되고 있는지 정의하기 위해이를 사용하려고했습니다. 방금 선택한 데이터 프레임 요소의 조건을 정의하는 데 사용했습니다. 그러나 당신은 그것을 알고 있었다 :-) –

24

시도 data.table:= 운영자 : 그것은 빠르고 짧다

DT = as.data.table(df) 
DT[b==0, est := (a-5)/2.533] 

. :=에 대한 자세한 내용은 다음 링크 질문을 참조하십시오 : 먼저 R-지옥 페이지에 대한 링크를 추가하면

Why has data.table defined :=

When should I use the := operator in data.table

How do you remove columns from a data.frame

R self reference

+0

아름답다, 모든 것에 대한 참조 +1. – PKumar

+0

매우 유용한 응답입니다. 이것을 사용한다면 DT는 data.table 패키지의 함수가 아니라 데이터 테이블 객체에 대한 참조라는 점에 유의하십시오. –

관련 문제