【问题标题】:Drop values of variables if they match one of other如果变量的值与其他变量之一匹配,则删除它们的值
【发布时间】:2014-11-06 20:08:09
【问题描述】:

我有一个这样的数据框:

Family   Component   x1   m_x1   x2   m_x2   x3   m_x3   y1   m_y1   y2   m_y2   y3   m_y3
a1       1           1    100    2    300    0    0      2    250    0    0      0    0
a1       2           1    100    2    300    0    0      2    250    0    0      0    01
a1       3           1    100    2    300    0    0      2    250    0    0      0    0
a2       1           2    150    0    0      0    0      0    0      0    0      0    0
a2       2           2    150    0    0      0    0      0    0      0    0      0    0
a3       1           1    4000   3    150    4    130    2    150    3    400    0    0
a3       2           1    4000   3    150    4    130    2    150    3    400    0    0
a3       3           1    4000   3    150    4    130    2    150    3    400    0    0
a3       4           1    4000   3    150    4    130    2    150    3    400    0    0

家庭是分组变量。然后我希望如果"Component"(对于每个Family)的值与x1x2x3y1y2y3 中的值不匹配,则该值该变量和下一个(对于x1m_x1,对于x2m_x2,...)被删除。我正在寻找的结果是:

Family   Component   x1   m_x1   x2   m_x2   x3   m_x3   y1   m_y1   y2   m_y2   y3   m_y3
a1        1           1    100    0    0      0    0      0    0      0    0      0    0
a1        2           0    0      2    300    0    0      2    250    0    0      0    0
a1        3           0    0      0    0      0    0      0    0      0    0      0    0
a2        1           0    0      0    0      0    0      0    0      0    0      0    0
a2        2           2    150    0    0      0    0      0    0      0    0      0    0
a3        1           1    4000   0    0      0    0      0    0      0    0      0    0
a3        2           0    0      0    0      0    0      2    150    0    0      0    0
a3        3           0    0      3    150    0    0      0    0      3    400    0    0
a3        4           0    0      0    0      4    130    0    0      0    0      0    0

我应该使用什么功能?我已经尝试过合并但无法使其工作。

【问题讨论】:

  • 在这个数据帧上使用melt 会使这个过程变得更容易。

标签: r merge dataframe


【解决方案1】:

这是一个简单的方法:

# find nonmatching entries
idx <- dat[-(1:2)][c(TRUE, FALSE)] != dat$Component

# full index
idx_full <- idx[ , rep(seq(ncol(idx)), each = 2)]

# replace values with 0
dat[-(1:2)][idx_full] <- 0

dat
#   Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3
# 1     a1         1  1  100  0    0  0    0  0    0  0    0  0    0
# 2     a1         2  0    0  2  300  0    0  2  250  0    0  0    0
# 3     a1         3  0    0  0    0  0    0  0    0  0    0  0    0
# 4     a2         1  0    0  0    0  0    0  0    0  0    0  0    0
# 5     a2         2  2  150  0    0  0    0  0    0  0    0  0    0
# 6     a3         1  1 4000  0    0  0    0  0    0  0    0  0    0
# 7     a3         2  0    0  0    0  0    0  2  150  0    0  0    0
# 8     a3         3  0    0  3  150  0    0  0    0  3  400  0    0
# 9     a3         4  0    0  0    0  4  130  0    0  0    0  0    0

dat 是您的数据框的名称。

【讨论】:

    【解决方案2】:

    如果列的顺序总是不同,你也可以这样做:

     n1 <- unique(gsub(".+\\_", "", colnames(df1)[-(1:2)]))
    
     df1[,-(1:2)] <- do.call(cbind,lapply(n1, function(x) {
                          indx <- grep(x, names(df1))
                          m1 <- as.matrix(df1[indx])
                          m1[m1[,1]!=df1$Component] <- 0
                          as.data.frame(m1) }))
      df1
      #   Family Component x1 m_x1 x2 m_x2 x3 m_x3 y1 m_y1 y2 m_y2 y3 m_y3
      #1     a1         1  1  100  0    0  0    0  0    0  0    0  0    0
      #2     a1         2  0    0  2  300  0    0  2  250  0    0  0    0
      #3     a1         3  0    0  0    0  0    0  0    0  0    0  0    0
      #4     a2         1  0    0  0    0  0    0  0    0  0    0  0    0
      #5     a2         2  2  150  0    0  0    0  0    0  0    0  0    0
      #6     a3         1  1 4000  0    0  0    0  0    0  0    0  0    0
      #7     a3         2  0    0  0    0  0    0  2  150  0    0  0    0
      #8     a3         3  0    0  3  150  0    0  0    0  3  400  0    0
      #9     a3         4  0    0  0    0  4  130  0    0  0    0  0    0
    

    【讨论】:

      【解决方案3】:

      你可以试试:

      cols <- as.vector(t(outer(c("x","y"), 1:3, 
                           function(...) paste(...,sep=""))))
      df[, 3:ncol(df)] <- do.call(cbind, lapply(cols, function(x) df[, 
                                    c(x,paste(sep="","m_",x))]*(df[[x]]==df$Component)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多