【问题标题】:Turn long dataset of classes taken into wide dataset where variables are dummy code for each class将类的长数据集转换为宽数据集,其中变量是每个类的虚拟代码
【发布时间】:2017-06-11 20:44:28
【问题描述】:

假设我有一个数据集,其中行是人们学习的类别:

attendance <- data.frame(id = c(1, 1, 1, 2, 2),
                         class = c("Math", "English", "Math", "Reading", "Math"))  

I.e.,

     id  class  
   1 1   "Math" 
   2 1   "English"
   3 1   "Math"
   4 2   "Reading"
   5 2   "Math"

我想创建一个新的数据集,其中行是 id,变量是类名,如下所示:

class.names <- names(table(attendance$class))
attedance2 <-  matrix(nrow=length(table(attendance$id)), 
                      ncol=length(class.names)) 
colnames(attedance2) <- class.names
attedance2 <- as.data.frame(attedance2)
attedance2$id <- unique(attendance$id)

I.e.,

     English  Math  Reading  id
   1    NA     NA      NA     1
   2    NA     NA      NA     2

我想在 NA 中填写该特定 ID 是否参加了该课程。它可以是是/否、1/0 或类的计数

I.e.,

     English  Math  Reading  id
   1   "Yes"  "Yes"   "No"    1
   2   "No"   "Yes"   "Yes"   2

我熟悉 dplyr,所以如果在解决方案中使用它但不是必需的,对我来说会更容易。感谢您的帮助!

【问题讨论】:

  • 基本上只是table(unique(attendance))

标签: r dplyr reshape reshape2


【解决方案1】:

使用:

library(reshape2)
attendance$val <- 'yes'
dcast(unique(attendance), id ~ class, value.var = 'val', fill = 'no')

给予:

  id English Math Reading
1  1     yes  yes      no
2  2      no  yes     yes

data.table类似的方法:

library(data.table)
dcast(unique(setDT(attendance))[,val:='yes'], id ~ class, value.var = 'val', fill = 'no')

或者dplyr/tidyr:

library(dplyr)
library(tidyr)
attendance %>% 
  distinct() %>% 
  mutate(var = 'yes') %>% 
  spread(class, var, fill = 'no')

另一个更复杂的选项可能是先重塑,然后用yesno 替换计数(有关dcast 的默认聚合选项,请参阅here for an explanation):

 att2 <- dcast(attendance, id ~ class, value.var = 'class')

给出:

  id English Math Reading
1  1       1    2       0
2  2       0    1       1

现在您可以将计数替换为:

# create index which counts are above zero
idx <- att2[,-1] > 0
# replace the non-zero values with 'yes'
att2[,-1][idx] <- 'yes'
# replace the zero values with 'no'
att2[,-1][!idx] <- 'no'

最终给出:

> att2
  id English Math Reading
1  1     yes  yes      no
2  2      no  yes     yes

【讨论】:

    【解决方案2】:

    我们可以通过base R 做到这一点

    attendance$val <- "yes"
    d1 <- reshape(attendance, idvar = 'id', direction = 'wide', timevar = 'class')
    d1[is.na(d1)] <- "no"
    names(d1) <- sub("val\\.", '', names(d1))
    d1
    #  id Math English Reading
    #1  1  yes     yes      no
    #4  2  yes      no     yes
    

    xtabs

    xtabs(val ~id + class, transform(unique(attendance), val = 1))
    #    class
    # id  English Math Reading
    #  1       1    1       0
    #  2       0    1       1
    

    注意:二进制可以轻松转换为“是”、“否”,但最好是 1/0 或 TRUE/FALSE

    【讨论】:

      猜你喜欢
      • 2020-08-14
      • 2019-07-07
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 2019-02-08
      • 2022-01-22
      • 2016-07-29
      • 1970-01-01
      相关资源
      最近更新 更多