转换R中的数据帧

时间:2011-03-30 19:55:18

标签: r

我有一个包含多个变量的数据框,而这些变量又有多个类别。我想把每个类别都转换成指标变量。

V1 V2 V3 V4
xc ab ty ky
xc ab ty kj
xc yi tf kj
cv yi tf kj
bg yt tg kl
bg yu yu kl

转换为

xc cv bg .....
T  F  F......
T  F  F....
T  F  F....
F  T  F....
F  F  T...
F  F  T....

我试过

newframe <- transform(oldframe, xc = to_column(oldframe$V1,'xc')) 

列的位置是

to_column = function(col, val){
    if (col == val)
        'TRUE'  else
        'FALSE' }

4 个答案:

答案 0 :(得分:7)

这是从分类变量创建虚拟变量的一种标准方法:

model.matrix( ~ V1 - 1, data=df)

df是您的问题所示的data.frame。这将返回0/1二进制作为您的FALSE / TRUE。希望有所帮助!

致以最诚挚的问候,

答案 1 :(得分:5)

在@ Jay的答案的基础上,我们将其作为逻辑矩阵。

逻辑矩阵版本:

out <- model.matrix( ~ V1 - 1, data=dat)
out <- matrix(as.logical(out), ncol = ncol(out))
colnames(out) <- with(dat, levels(V1))

> out
        bg    cv    xc
[1,] FALSE FALSE  TRUE
[2,] FALSE FALSE  TRUE
[3,] FALSE FALSE  TRUE
[4,] FALSE  TRUE FALSE
[5,]  TRUE FALSE FALSE
[6,]  TRUE FALSE FALSE

所有变量一次版本:

out2 <- sapply(dat, function(x) model.matrix( ~ x - 1))
out2 <- do.call(cbind, out2)
out2 <- matrix(as.logical(out2), ncol = ncol(out2))
colnames(out2) <- unlist(sapply(dat, levels))

> out2
        bg    cv    xc    ab    yi    yt    yu    tf    tg    ty
[1,] FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
[2,] FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
[3,] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
[4,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE
[5,]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
[6,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
        yu    kj    kl    ky
[1,] FALSE FALSE FALSE  TRUE
[2,] FALSE  TRUE FALSE FALSE
[3,] FALSE  TRUE FALSE FALSE
[4,] FALSE  TRUE FALSE FALSE
[5,] FALSE FALSE  TRUE FALSE
[6,]  TRUE FALSE  TRUE FALSE

如果您不希望将此作为上面的完整矩阵,则可以使用第一行停止,第一行包含列表中的所有模型矩阵,dat中的每个变量(列)都有一个,并将其转换为逻辑。这个单线程执行两个步骤:

> lapply(lapply(dat, function(x) model.matrix( ~ x - 1)),
+        function(x) matrix(as.logical(x), ncol = ncol(x)))
$V1
      [,1]  [,2]  [,3]
[1,] FALSE FALSE  TRUE
[2,] FALSE FALSE  TRUE
[3,] FALSE FALSE  TRUE
[4,] FALSE  TRUE FALSE
[5,]  TRUE FALSE FALSE
[6,]  TRUE FALSE FALSE

$V2
      [,1]  [,2]  [,3]  [,4]
[1,]  TRUE FALSE FALSE FALSE
[2,]  TRUE FALSE FALSE FALSE
[3,] FALSE  TRUE FALSE FALSE
[4,] FALSE  TRUE FALSE FALSE
[5,] FALSE FALSE  TRUE FALSE
[6,] FALSE FALSE FALSE  TRUE

$V3
      [,1]  [,2]  [,3]  [,4]
[1,] FALSE FALSE  TRUE FALSE
[2,] FALSE FALSE  TRUE FALSE
[3,]  TRUE FALSE FALSE FALSE
[4,]  TRUE FALSE FALSE FALSE
[5,] FALSE  TRUE FALSE FALSE
[6,] FALSE FALSE FALSE  TRUE

$V4
      [,1]  [,2]  [,3]
[1,] FALSE FALSE  TRUE
[2,]  TRUE FALSE FALSE
[3,]  TRUE FALSE FALSE
[4,]  TRUE FALSE FALSE
[5,] FALSE  TRUE FALSE
[6,] FALSE  TRUE FALSE

如果变量名称很重要,那么我们可以将其修改为

foo <- function(x) {
    mat <- matrix(as.logical(x), ncol = ncol(x))
    colnames(mat) <- levels(x)
    mat
}
lapply(lapply(dat, function(x) model.matrix( ~ x - 1)), foo)

答案 2 :(得分:1)

您可以查看reshape包,它提供了像这样的数据透视功能。有使用at the author's homepage

的例子

答案 3 :(得分:1)

使用“qdap”包中的mtabulate非常简单:

library(qdap)
mtabulate(split(mydf, 1:nrow(mydf))) > 0
#      ab    bg    cv    kj    kl    ky    tf    tg    ty    xc    yi
# 1  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE
# 2  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE
# 3 FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE
# 4 FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE
# 5 FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
# 6 FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
#      yt    yu
# 1 FALSE FALSE
# 2 FALSE FALSE
# 3 FALSE FALSE
# 4 FALSE FALSE
# 5  TRUE FALSE
# 6 FALSE  TRUE

默认情况下,mtabulate会将结果列表(惊喜!),因此结果将是数字data.frame。例如,您将看到第6行中“yu”的计数实际为2.要获得您想要的logical输出(只是存在/不存在),只需比较从{{1}获得的值零。