【问题标题】:R - Apply and remove columnsR - 应用和删除列
【发布时间】:2014-03-12 00:09:47
【问题描述】:

我有一个名为 dtdata.frame,它看起来像:

row.names     A     B     C     D
        1   0.1   0.2   0.5   0.3
        2   0.2   0.3   0.4     0
        3    10  -0.1  -0.3   0.3 # remove A cause 10 / 0.2 > 2

如果X[i]/X[i-1]>2,i>=2,我想删除列X。 即如果当前行除以上一行大于2(增加两倍),则删除该列。

我已经尝试过apply 像这样:

temp<-dt
val<-apply(temp,2,function(y) {
  y<-na.omit(y) # omit na
  ans1 <- y[-1,] / y[-nrow(y),] - 1 # divide previous row
  if (max(ans1,na.rm=TRUE)>2) {
    y<-NULL # remove from temp
  }
})

但它似乎并没有从temp 中删除该行。我想过可能会返回colnames 的列表,但我无法以我的方式从apply 中获取它们。

有什么想法吗?

谢谢。

=== 编辑 ===
用lukeA的答案的修改版本想出来:

val<-sapply(dt,function(y) {
  y2<-na.omit(y) # omit NA
  ans1 <- y2[-1] / y2[-length(y2)] - 1 # divide previous row
  if (max(ans1,na.rm=TRUE)>1.5|min(ans1,na.rm=TRUE)< -0.5) {
    return(NULL) # return all NULL
  } else {
    return(y) # return original
  }
})

【问题讨论】:

    标签: r function matrix apply division


    【解决方案1】:

    这会将您的 A 值转换为 NA(不可用):

    dt$A[-1] <- ifelse(dt$A[-1] / head(dt$A[-1], -1) > 2, NA, dt$A[-1])
    

    现在您可以决定如何处理 A 列中的 NAs,例如删除行:

    dt <- dt[!is.na(dt$A), ]
    

    这也适用于所有列,如下所示:

    dt[, -1] <- sapply(dt[, -1], function(x) {
      x[-1] <- ifelse(x[-1] / head(x[-1], -1) > 2, NA, x[-1])
      x
    })
    dt <- na.omit(dt) # remove NA rows
    

    如果你想用NA删除列,你可以这样做:

    dt[, c(1, which(!is.na(colSums(dt[, -1]))))]
    

    【讨论】:

    • 感谢您的回复,有没有办法像apply 那样对每一列都执行此操作?矩阵dt 只是一个小例子,我会为一个非常大的矩阵做它(想想300x300 及以上)。
    • @Ubobo dt[, -1]除了第一列之外的每一列,所以:是的。但是,ifelse 并不是最快的。另一方面,colSums 是超快的。试试看。
    • 谢谢,我正在编辑我的评论,但它超时了:O!我用dt[,-1] 尝试了那个,但我得到了错误50: In x[-1]/head(x[-1], -1) : longer object length is not a multiple of shorter object length。结果dt 为空。
    • @Ubobo 我无法用您的示例数据重现错误。您的数据中是否已经存在NAs?
    • 别担心,我用你的一个修改过的它来工作:),请参阅 OP 编辑​​。谢谢老兄。
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多