首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dcast重塑数据?

使用dcast重塑数据?
EN

Stack Overflow用户
提问于 2013-08-07 20:43:30
回答 4查看 2K关注 0票数 2

我不知道使用dcast()是否正确,但我想重塑以下data.frame:

代码语言:javascript
复制
df <- data.frame(x=c("p1","p1","p2"),y=c("a","b","a"),z=c(14,14,16))
df
   x y  z
1 p1 a 14
2 p1 b 14
3 p2 a 16

所以看起来就像这个:

代码语言:javascript
复制
df2 <- data.frame(x=c("p1","p2"),a=c(1,1),b=c(1,0),z=c(14,16))
   x a b  z
1 p1 1 1 14
2 p2 1 0 16

应该破坏df中的变量df,以便它的元素是新变量,每个虚拟编码变量。所有其他变量(在本例中仅为z)对于每个人(p1、p2等)是相等的。特定人p具有不同值的唯一变量是y

我之所以需要这样做,是因为我需要通过变量x将此数据集与其他数据集合并。问题是,它需要每人一行(p1、p2等)。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-08 00:00:33

这几乎是一个previous question的复制,我在那里使用的相同的基本答案再次起作用。也不需要任何外部包。

代码语言:javascript
复制
aggregate(model.matrix(~ y - 1, data=df),df[c("x","z")],max)

   x  z ya yb
1 p1 14  1  1
2 p2 16  1  0

为了解释这一点,由于看起来有点奇怪,model.matrix调用在其最基本的位置为data.frame的每一行返回一个二进制指示符变量,如下所示:

代码语言:javascript
复制
  ya yb
1  1  0
2  0  1
3  1  0

如果通过两个id变量(xz)对中间结果进行操作,那么实际上是对以下两个变量的初始data.frame进行操作:

代码语言:javascript
复制
   x  z ya yb
1 p1 14  1  0
2 p1 14  0  1
3 p2 16  1  0

因此,如果在maxz的每个组合中取yaybyb值,那么基本上是这样的:

代码语言:javascript
复制
   x  z ya      yb
1 p1 14  1*max*  0
2 p1 14  0       1*max*

--collapse--

   x  z ya      yb
1 p1 14  1       1

...and对每个唯一的x/z组合重复这一步骤,以给出最终结果:

代码语言:javascript
复制
   x  z ya yb
1 p1 14  1  1
2 p2 16  1  0

把它推广到更多的专栏有些疯狂,但这是可以做到的,这要归功于this question,例如:

代码语言:javascript
复制
df <- data.frame(x=c("p1","p1","p2"),y=c("a","b","a"),z=c("14","15","16"))
intm <- model.matrix(~ y + z - 1, data=df,
                 contrasts.arg = sapply(df[2:3], contrasts, contrasts=FALSE))
aggregate(intm,df[c("x")],max)

   x ya yb z14 z15 z16
1 p1  1  1   1   1   0
2 p2  1  0   0   0   1
票数 2
EN

Stack Overflow用户

发布于 2013-08-07 20:52:21

以下的工作,但似乎繁琐。

代码语言:javascript
复制
df2 <- df
df2$y <- as.numeric(y)
df$y2 <- as.numeric(df$y)

df2 <- dcast(df, x+z~y, value.var="y2")

df2
   x  z a  b
1 p1 14 1  2
2 p2 16 1 NA
票数 2
EN

Stack Overflow用户

发布于 2013-08-07 23:17:48

我不确定您需要做什么,但是如果您需要一种自动化的方法,我编写了一个小函数,它可能会有帮助:

第一次运行dcast:

代码语言:javascript
复制
new = dcast(df, x+z~y, value.var="y")

加载到您的R环境:

代码语言:javascript
复制
 # args to be passed: 
 # df is your dataframe 
 # cols is a list of format c("colname1", "colname2", ... , "colnameN")
    binarizeCols = function(df, cols){
      for(i in cols){
        column = which(colnames(df) == i)
        truthRow = is.na(df[,column])
        for(j in 1:length(truthRow)){
          if(truthRow[j] == FALSE){
            df[j,column] = 1
          }else{
             df[j,column] = 0
           }
        }
      }
      return(df)
    }

然后跑:

代码语言:javascript
复制
new = binarizeCols(new, c("a", "b"))

你得到的是:

代码语言:javascript
复制
     x  z  a  b
   1 p1 14 1  1 
   2 p2 16 1  0

不像使用_apply()那么快,但是没有硬编码,您可以输入任何你想要的名字(也许你想在中间跳过一个?)而且您也不会创建df的新实例。注意:我使用"=“而不是"<-”,因为我认为它正在逐步淘汰,但是如果需要的话可以替换它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18113443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档