2015-05-05 32 views
4

任何使用data.table或dplyr解决以下问题的方法?从三列data.table返回所有因子级别的名称作为新列[R]

library(data.table) 

(DT = data.table(a = LETTERS[c(1, 1:3, 8)], b = c(2, 4:7), 
       c = as.factor(c("bob", "mary", "bob", "george", "alice")), key="a")) 

返回:

# a b  c 
# 1: A 2 bob 
# 2: A 4 mary 
# 3: B 5 bob 
# 4: C 6 george 
# 5: H 7 alice 

想获得这样的:

#  alice bob george mary 
# 1: A NA 2 NA  NA 
# 2: A NA NA NA  4 
# 3: B NA 5 NA  NA 
# 4: C NA NA 6  NA 
# 5: H 7 NA NA  NA 
+1

可能不是很好的做法来命名任何'c',因为我们始终使用该函数。 – Frank

+0

好点。无论如何,您的解决方案效率高。 –

+0

如果你最终希望得到一个'a'的单个行,可以使用[tidyr]中的'spread(DT,c,b)'(http://cran.r-project.org/web/packages/ tidyr/vignettes/tidy-data.html)包。 –

回答

4

这类似于creating dummy variables

uc <- sort(unique(as.character(DT$c))) 
DT[,(uc):=lapply(uc,function(x)ifelse(c==x,b,NA))][,c('b','c'):=NULL] 

我听到坏话ifelse,所以速度更快的路线可能是

uc <- sort(unique(as.character(DT$c))) 
is <- 1:nrow(DT) 
js <- as.character(DT$c) 
vs <- DT$b 

DT[,(uc):=NA_integer_] 
for (i in is) set(DT,i=is[i],j=js[i],value=vs[i]) 

DT[,c('b','c'):=NULL] 
+0

好答案@Frank!能够稍微修改以删除** b **和** c **列:'DT [,(uc):= lapply(uc,function(x)ifelse(c == x,b,NA)) ] [,!c(“b”,“c”),with = FALSE] –

+1

@BobHopez谢谢:)我忘了放弃b,但现在已经添加了它。如果您通过设置为NULL来引用(如答案中所示),则可以从'DT'中删除'b'和'c',并且不需要创建新表。相反,如果你使用'with = FALSE',你需要像'newDT < - DT [...,with = FALSE]一样赋值'来进一步使用结果,复制(需要时间和记忆)。 – Frank

+0

无法让您的底部代码块工作@Frank。上半部分完美运作。 –

3

刚开始使用虚拟变量从弗兰克的想法:

df1 <- cbind(a = DT$a, as.data.frame(model.matrix(a ~ c - 1, data = DT) * DT$b)) 
df1[df1==0] <- NA 
names(df1) <- c("a", levels(DT$c)) 

# a alice bob george mary 
# 1 A NA 2  NA NA 
# 2 A NA NA  NA 4 
# 3 B NA 5  NA NA 
# 4 C NA NA  6 NA 
# 5 H  7 NA  NA NA 
+0

几乎在那里......将列名更改为** paste0(“c”,names)**。 –

+0

是的,model.matrix做到了这一点(将变量名与层级结合起来)。我将名称更改为原始因子水平。 – bergant

+0

这里是[后续问题](http://stackoverflow.com/questions/30065418/follow-up-matching-factor-levels-in-r-with-shared-unique-row-names) –

2

随着碱R:

names <- unique(as.character(DT$c)) 
cbind(a = DT$a, as.data.frame(sapply(names, function(x) ifelse(DT$c==x, DT$b, NA)))) 
相关问题