2013-08-14 2 views
62

나는 다른 열 차례 하나를 기반으로 데이터 프레임을 주문하고 싶습니다.동적으로 선택 데이터 프레임 열

:

parameter <- c("market_value_LOCAL", "ep", "book_price", "sales_price", "dividend_yield", 
       "beta", "TOTAL_RATING_SCORE", "ENVIRONMENT", "SOCIAL", "GOVERNANCE") 

내가 order 내 데이터를 사용할 수 parameter의 이름을 통해 루프하고자 동적으로 열을 선택 : 나는 order 기반해야하는 관련 열 이름과 문자 벡터가

Q1_R1000_parameter <- Q1_R1000[order(Q1_R1000$parameter[X]), ] 

여기에서 X1:10입니다 (왜냐하면 parameter에 10 개의 항목이 있기 때문입니다).


데이터를 고려, 내 예를 재현 할 수 있도록 문자 벡터 cols에 저장 mtcars 일부 변수 이름을 설정합니다. 나는 위와 같이 ( Q1_R1000$parameter[X])을 비슷한 방식으로, cols의 동적 집합을 사용하여 mtcars에서 변수를 선택하려고 할 때, 열이 선택되지 않습니다

cols <- c("cyl", "am") 
mtcars$cols[1] 
# NULL 

답변

102

당신은 $와 서브 세트의 종류를 할 수없는 소스 코드에서 (R/src/main/subset.c는) 그 상태 :

/* $ 하위 집합 연산자
첫 번째 인수 만 평가해야합니다.
두 번째 기호는 일치시켜야하며 평가되지 않아야합니다.
*/

두 번째 인수? 뭐?! 당신은 R에서 다른 모든 것들처럼, 인수를 평가하는 기능이있다 (예를 (, +, ^ 등을 위해 포함) $ 것을 깨닫게해야합니다. df$V1이 작동하지 않습니다 예를 들어 ...

`$`(df , V1) 

또는 실제로

`$`(df , "V1") 

그러나 같은

`$`(df , paste0("V1")) 

을 다시 작성할 수 없으며, 다른 것을 먼저 평가해야 것 두 번째 인수에서 당신은 평가 결코 인 문자열을 전달할 수 있습니다.

벡터 대신 단일 열을 추출하려면 [ (또는 [[)을 사용하십시오. 당신은 order에 대한 호출을 구성 do.call를 사용하여, 루프없이 순서를 수행 할 수

var <- "mpg" 
#Doesn't work 
mtcars$var 
#These both work, but note that what they return is different 
# the first is a vector, the second is a data.frame 
mtcars[[var]] 
mtcars[var] 

예를 들어

. 여기에 아래의 재현 예입니다 dplyr를 사용

# set seed for reproducibility 
set.seed(123) 
df <- data.frame(col1 = sample(5,10,repl=T) , col2 = sample(5,10,repl=T) , col3 = sample(5,10,repl=T)) 

# We want to sort by 'col3' then by 'col1' 
sort_list <- c("col3","col1") 

# Use 'do.call' to call order. Seccond argument in do.call is a list of arguments 
# to pass to the first argument, in this case 'order'. 
# Since a data.frame is really a list, we just subset the data.frame 
# according to the columns we want to sort in, in that order 
df[ do.call(order , df[ , match(sort_list , names(df)) ] ) , ] 

    col1 col2 col3 
10 3 5 1 
9  3 2 2 
7  3 2 3 
8  5 1 3 
6  1 5 4 
3  3 4 4 
2  4 3 4 
5  5 1 4 
1  2 5 5 
4  5 3 5 
1

내가 제대로 이해한다면, 당신은 변수를 포함하는 벡터를 가지고 이름을 입력하고 각 이름을 반복하고 데이터 프레임을 정렬합니다. 그렇다면이 예는 당신을위한 해결책을 설명해야합니다. 당신의 주요 문제는 매개 변수가 아닌 변수 이름을 포함하는 외부 객체이기 때문에 그것을 대신 order(Q1_R1000$parameter[X])order(Q1_R1000[,parameter[X]])해야한다는 것입니다 (전체 예를 들어 내가 "다른 사람이 누락 될 수 있습니다 무엇을 잘 모르겠어요 너무 완료되지 않음) ..합니다 ($ 적절한 것) 데이터 프레임의 직접 열

set.seed(1) 
dat <- data.frame(var1=round(rnorm(10)), 
        var2=round(rnorm(10)), 
        var3=round(rnorm(10))) 
param <- paste0("var",1:3) 
dat 
# var1 var2 var3 
#1 -1 2 1 
#2  0 0 1 
#3 -1 -1 0 
#4  2 -2 -2 
#5  0 1 1 
#6 -1 0 0 
#7  0 0 0 
#8  1 1 -1 
#9  1 1 0 
#10 0 1 0 

for(p in rev(param)){ 
    dat <- dat[order(dat[,p]),] 
} 
dat 
# var1 var2 var3 
#3 -1 -1 0 
#6 -1 0 0 
#1 -1 2 1 
#7  0 0 0 
#2  0 0 1 
#10 0 1 0 
#5  0 1 1 
#8  1 1 -1 
#9  1 1 0 
#4  2 -2 -2 
0
Q1_R1000[do.call(order, Q1_R1000[parameter]), ] 
1

가 제공하는 데이터를 정렬하는 쉬운 구문이 프레임은

library(dplyr) 
mtcars %>% arrange(gear, desc(mpg)) 

일종의 구축을 동적으로 허용하는 NSE 버전을 사용하는 것이 유용 할 수 있습니다 목록

sort_list <- c("gear", "desc(mpg)") 
mtcars %>% arrange_(.dots = sort_list) 
+0

NSE 여기에 무엇을 의미 하는가 사용

내가 목록에 첫 번째 유효한 열 이름을 반환하는 함수를 썼다 :
이 해결책인가? – discipulus

+1

@ discisculus 비표준 평가; 지연된 표현식을 사용하여 하드 코딩 대신 문자열로 코드를 동적으로 빌드하기위한 것입니다. 자세한 정보는 여기를 참조하십시오 : https://cran.r-project.org/web/packages/lazyeval/vignettes/lazyeval.html – manotheshark

-1

때문에 SAM에 대한 다양한 이름을 가지고 일부 CSV 파일에 비슷한 문제가 있었다 전자 칼럼. 그 다음은 ...

# Return the string name of the first name in names that is a column name in tbl 
# else null 
ChooseCorrectColumnName <- function(tbl, names) { 
for(n in names) { 
    if (n %in% colnames(tbl)) { 
     return(n) 
    } 
} 
return(null) 
} 

then... 

cptcodefieldname = ChooseCorrectColumnName(file, c("CPT", "CPT.Code")) 
icdcodefieldname = ChooseCorrectColumnName(file, c("ICD.10.CM.Code", "ICD10.Code")) 

if (is.null(cptcodefieldname) || is.null(icdcodefieldname)) { 
     print("Bad file column name") 
} 

# Here we use the hash table implementation where 
# we have a string key and list value so we need actual strings, 
# not Factors 
file[cptcodefieldname] = as.character(file[cptcodefieldname]) 
file[icdcodefieldname] = as.character(file[icdcodefieldname]) 
for (i in 1:length(file[cptcodefieldname])) { 
    cpt_valid_icds[file[cptcodefieldname][i]] <<- unique(c(cpt_valid_icds[[file[cptcodefieldname][i]]], file[icdcodefieldname][i])) 
} 
관련 문제