2017-07-25 4 views
-1

私は、このデータフレーム1の場合、列名(A、B、Cで列A、BおよびCとDを移入するための最良の方法は何は、他の列

dat = data.frame(Type = c("A","A","B","B","C","C","D"), NextType = c("A", "B","B", "C","C","D",NA), 
       A = c(rep(0,7)), 
       B = rep(0,7), 
       C = rep(0,7) , 
       D = rep(0,7), 
       stringsAsFactors = F) 
dat 

Type NextType A B C D 
1 A  A 0 0 0 0 
2 A  B 0 0 0 0 
3 B  B 0 0 0 0 
4 B  C 0 0 0 0 
5 C  C 0 0 0 0 
6 C  D 0 0 0 0 
7 D  <NA> 0 0 0 0 

を持っているを使用して、特定の列の式を適用します、D等...)=タイプ= NextType

ので

column A would be 1,0,0,0,0,0,0 
column B would be 0,0,1,0,0,0,0 
column C would be 0,0,0,0,1,0,0 
column D would be 0,0,0,0,0,0,0 

注 - これは、動的にする必要があります。私はA、B、C、Dの上に4列ありますが、10,20、または任意の数の列があります。

答えて

1

使用dplyrtidyr

library(dplyr); library(tidyr); 

dat %>% 
    select(Type, NextType) %>% 
    mutate(key = if_else(Type == NextType & !is.na(Type) & !is.na(NextType), Type, "other"), 
      val = 1) %>% 
    spread(key, val, fill = 0) %>% 
    select(-other) 

# Type NextType A B C 
#1 A  A 1 0 0 
#2 A  B 0 0 0 
#3 B  B 0 1 0 
#4 B  C 0 0 0 
#5 C  C 0 0 1 
#6 C  <NA> 0 0 0 

データ

dat = data.frame(Type = c("A","A","B","B","C","C"), NextType = c("A", "B","B", "C","C",NA), A = c(rep(0,6)), B = rep(0,6), C = rep(0,6) , stringsAsFactors = F) 
+0

申し訳ありません。あなたは編集を見ることができますか? – user3022875

+0

したがって、排他的にゼロの列が欲しいですか? – Psidom

+0

この場合、 'model.matrix'を試すことができます。' Type'列+ otherと同じレベルのfactor型のキー列を作成し、 'model.matrix'は余分なレベルを保持します。タイプ= "Next")、タイプ( "!"(タイプ)&!is.na(次のタイプ)、タイプ、 "その他")、 %>%select(-keyother、 - )は、指定されたキーを使用して、キー) ' – Psidom

1

私はこのようにこれを行うだろう:

library(tidyr) 
library(dplyr) 
dat = data.frame(Type = c("A","A","B","B","C","C"), NextType = c("A", "B","B", "C","C",NA)) 
dat <- dat %>% mutate(A=ifelse(Type == NextType & Type == 'A', 1, 0),B=ifelse(Type == NextType & Type == 'B', 1, 0),C=ifelse(Type == NextType & Type == 'C', 1, 0)) 
+0

感謝が、それは – user3022875

0

ダイナミックEDIT

library(data.table) 
dat = data.table(Type = c("A","A","B","B","C","C"), NextType = c("A", "B","B", "C","C",NA), 
      A = c(rep(0,6)), B = rep(0,6), C = rep(0,6)) 
dat 

dat[Type=="A", A:=(Type == NextType)] 
dat[Type=="B", B:=(Type == NextType)] 
dat[Type=="C", C:=(Type == NextType)] 

data.tableで(おそらく、多分誰かが他の提案を非常に効率的でありません?)

mycols <- names(dat)[!(names(dat) %in% c("Type", "NextType"))] 
for(i in mycols){ 
    dat[Type==i, (i) := (Type==NextType)] 
} 
+0

はあなたが任意の数の列のためにそれを動的に行うことができます任意の数の列を処理するために動的にする必要があります編集 – user3022875

+0

編集を参照してください。それはあなたが望むことをします。どのくらい効率的かわからない – simone

1

model.matrix,diff、およびapplyを使用する方法があります。

cbind(dat[1], apply(model.matrix(~Type-1, dat), 2, function(x) c(x[1], diff(x) > 0))) 

model.matrix(~Type-1, dat)対応する値が列に存在する場合、各列は1ダミー変数の行列を返します。これはapplyに供給され、各列を取り、その列の最初の値とその差が0より大きいかどうかの評価を返します。結果の行列はcbindを使用して最初の列と結合されます。あなたは、同様に第二のカラムが含まdf[1:2]df[1]を変更したい場合

Type TypeA TypeB TypeC 
1 A  1  0  0 
2 A  0  0  0 
3 B  0  1  0 
4 B  0  0  0 
5 C  0  0  1 
6 C  0  0  0 

を返し


lapplyを使用して別の基地R法は、我々は、DAT $タイプの一意の値を介して、

dat[, LETTERS[1:3]] <- lapply(unique(dat$Type), 
           function(x) (dat$Type == x) * !duplicated(dat$Type)) 

ここサイクルであり、DAT $タイプの各要素は、この値とIF等しいかどうかをチェック要素は重複しています。これは、dat内の対応する変数に割り当てられたリストを返します。