Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从三列data.table[R]中按名称将所有因子级别作为新列返回_R_Data.table_Dplyr - Fatal编程技术网

从三列data.table[R]中按名称将所有因子级别作为新列返回

从三列data.table[R]中按名称将所有因子级别作为新列返回,r,data.table,dplyr,R,Data.table,Dplyr,有没有办法使用data.table或dplyr来解决以下问题 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

有没有办法使用data.table或dplyr来解决以下问题

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
这类似于


仅使用Frank的虚拟变量思想:

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
df1带基数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))))

命名可能不是命名任何东西的好方法,因为我们一直都在使用这个函数。无论如何,您的解决方案工作效率很高!如果您最终希望
a
的每个值都有一行,请使用包中的
spread(DT,c,b)
dcast(DT[,I:=.I],a+I~c,value.var=“b”)
回答得好@Frank!能够稍微修改以删除b和c列:
DT[,(uc):=lapply(uc,函数(x)ifelse(c==x,b,NA))[,!c(“b”,“c”),with=FALSE]
@BobHopez谢谢:)我忘记删除b,但现在已经添加了它。如果您通过设置为
NULL
以引用方式删除(如答案中所示),则可以从
DT
中删除
b
c
,而无需创建新表。相反,如果你用=FALSE做
with
的事情,你需要像
newDT那样分配它,不能让你的底层代码块@Frank工作。上半部分工作得很好。运行for loop后获得的j是-2147483648,超出范围[1,ncol=5]。嗯,如果您删除
DT
,按照您的问题重新创建它,然后运行下半部分,它不工作吗?几乎就在那里了。。。将列名更改为paste0(“c”,名称)。是的,model.matrix会这样做(将变量名与级别组合)。我将名称更改为原始因子级别
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
names <- unique(as.character(DT$c))
cbind(a = DT$a, as.data.frame(sapply(names, function(x) ifelse(DT$c==x, DT$b, NA))))