【问题标题】:R Finding the missing rowsR查找丢失的行
【发布时间】:2013-08-31 18:49:50
【问题描述】:

假设我有两个数据框 df1,df2,看起来像:

df1

        User        Lab      Score
         A           1        52
         A           2        65
         A           3        87
         A           5        78
         B           2        56
         B           4        98
         C           6        78

然后我有另一个数据框,我将用户 A 与数据框的其余部分隔离开来。

df2

        User       Lab      Score
        A          1         52
        A          2         65
        A          3         87
        A          5         78

如果我想创建一个包含 df2 中所有行的数据框,并且如果用户没有尝试过实验室,则他们的分数为 0。 所以我想要:

df3

        User       Lab      Score
        A          1         52
        A          2         65
        A          3         87
        A          4         0
        A          5         78                
        A          6         0 

【问题讨论】:

  • 你怎么知道用户现在没有尝试实验室?是否设置为 NA?

标签: r loops dataframe rows


【解决方案1】:

为什么不使用data.table 一次性完成所有操作?

FinalTable = data.table(User=unique(df1$User))[,list(Lab=1:6),by=User]
setkey(FinalTable, User, Lab)
setkey(df1, User, Lab)
FinalTable = df1[FinalTable]
FinalTable[is.na(Score),Score:=0L]

结果:

    User Lab Score
 1:    A   1    52
 2:    A   2    65
 3:    A   3    87
 4:    A   4     0
 5:    A   5    78
 6:    A   6     0
 7:    B   1     0
 8:    B   2    56
 9:    B   3     0
10:    B   4    98
11:    B   5     0
12:    B   6     0
13:    C   1     0
14:    C   2     0
15:    C   3     0
16:    C   4     0
17:    C   5     0
18:    C   6    78

【讨论】:

    【解决方案2】:

    我确信有更好的方法来做到这一点,但这是我能想到的:

     ##Get unique lab IDs
     labs = as.data.frame(unique(df$Lab))
     names(labs) <- "Lab"
    
     df3 = merge(df2, labs, all.y = TRUE)
     df3$User[is.na(df3$User)] <- "A"
     df3[is.na(df3)] <- 0
     df3 <- df3[,c(2,1,3)]
    
    
     #> df3
     #  User Lab Score
     #1    A   1    52
     #2    A   2    65
     #3    A   3    87
     #4    A   4     0
     #5    A   5    78
     #6    A   6     0
    

    【讨论】:

    • +1。我正要建议full &lt;- data.frame(User = rep(LETTERS[1:3], each = 6), Lab = 1:6); final &lt;- merge(df1, full, by = c("User", "Lab"), all = TRUE); final[is.na(final)] &lt;- 0,假设他们最终会想要为所有“用户”这样做。
    • 或者:完整的
    【解决方案3】:
    User<-c(rep('A',4),rep('B',2),'C')
    Lab<-c(1,2,3,4,5,2,6)
    Score<-c(52,65,87,78,56,98,78)
    df1<-data.frame(User,Lab,Score)
    df2<-df1[df1$User=='A',]
    ## find different value of df1$Lab and df2$Lab
    s1<-unique(df1$Lab)
    s2<-unique(df2$Lab)
    ## compute length
    f1<-length(s1)-length(s2)
    f2<-dim(df2)[1]
    ## initiate df3
    df3<-df2
    ## expand df3, setdiff means the difference of two sets 
    df3[(f2+1):(f2+f1),]<-data.frame(rep('A',f1),setdiff(s1,s2),rep(0,f1))
    

    【讨论】:

      【解决方案4】:

      如果您愿意使用矩阵(并且每个用户/实验室都有唯一的记录),那么您可以使用 tapply:

      mat1 <- tapply(df1$Score, list(df1$Lab, df1$User), mean)
      mat1[is.na(mat1)] <- 0
      mat1
      
      #   A   B  C
      # 1 52  0  0
      # 2 65 56  0
      # 3 87  0  0
      # 4  0 98  0
      # 5 78  0  0
      # 6  0  0 78
      

      现在每一列都代表一个用户,很容易按用户提取统计信息:

      apply(mat1, 2, mean)
      apply(mat1, 2, sd)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多