【问题标题】:Replace values in each column based on conditions according to groups (by rows) data.frame根据组(按行)data.frame 根据条件替换每列中的值
【发布时间】:2013-09-30 12:51:35
【问题描述】:

我有一个 data.frame,dim = 400 行和 15000 列。我想应用一个条件,对于属于每个组的行,由df$Group 定义,我必须检查该组是否在超过 50% 的行中具有值。如果是,则保留现有值,否则全部替换为0

例如,对于组 a df[1:6,1]if sum(df[1:6,1] == 0)/length(df[1:6,1]) >50%,那么df[1:6,1] 中的所有值都将替换为0。否则现有值将保留。

示例输入:

df <- read.table(text= "DATA  r1    r2  r3  Group
a1  6835    256 0   a
a2  5395    0   67  a
a3  7746    0   30  a
a4  7496    556 50  a
a5  5780    255 0   a
a6  6060    603 0   a
b1  0   0   0   b
b2  0   258 0   b
b3  0   0   0   b
b4  0   0   0   b
b5  5099    505 0   b
b6  0   680 0   b
c1  8443    4900    280 c
c2  8980    4949    0   c
c3  7828    0   0   c
c4  6509    3257    0   c
c5  6563    0   49  c
", header=TRUE, na.strings=NA,row.name=1)
dt <- as.data.table(df) #or data.frame

预期输出:

>df
DATA   r1     r2    r3  Group
 a1   6835   256    0     a
 a2   5395     0   67     a
 a3   7746     0   30     a
 a4   7496   556   50     a
 a5   5780   255    0     a
 a6   6060   603    0     a
 b1      0     0    0     b
 b2      0   258    0     b
 b3      0     0    0     b
 b4      0     0    0     b
 b5      0   505    0     b
 b6      0   680    0     b
c1    8443  4900    0     c
c2    8980  4949    0     c
c3    7828     0    0     c
c4    6509  3257    0     c
c5    6563     0    0     c

【问题讨论】:

    标签: r dataframe data.table


    【解决方案1】:

    更新:#4957 这个错误现已在v1.8.11 中修复。来自NEWS

    修复 #5007 还修复了 #4957,其中 .Nlapply(.SD, function(x) ...)j 期间不可见。感谢 juba 在 SO 上注意到它:Replace values in each column based on conditions according to groups (by rows) data.frame


    这是data.table的一种方式:

    dt[, lapply(.SD, function(v) {
        len <- length(v)
        if((sum(v==0)/len)>0.5) rep(0L,len) else v
    }), by="Group", .SDcols=c("r1","r2","r3")]
    

    这给出了:

       Group   r1   r2 r3
     1:     a 6835  256  0
     2:     a 5395    0 67
     3:     a 7746    0 30
     4:     a 7496  556 50
     5:     a 5780  255  0
     6:     a 6060  603  0
     7:     b    0    0  0
     8:     b    0  258  0
     9:     b    0    0  0
    10:     b    0    0  0
    11:     b    0  505  0
    12:     b    0  680  0
    13:     c 8443 4900  0
    14:     c 8980 4949  0
    15:     c 7828    0  0
    16:     c 6509 3257  0
    17:     c 6563    0  0
    

    【讨论】:

    • 太好了!谢谢@juba。正是我想要的! data.table 确实加快了我们处理大型数据集的计算时间。
    • @MatthewDowle 不能按原样与lapply 一起使用-您需要按照lapply(.SD, function(v, .N){...}, .N) 的方式进行操作(除非我运行的是旧版本的data.table 和那个问题已经修复了吗?)
    • @MatthewDowle 它对我也不起作用.N,这就是我使用length的原因...
    • @eddi,朱巴。哦,对不起。将恢复编辑。已提交bug #4957
    • @MatthewDowle 没问题!感谢您的评论、错误报告,最重要的是感谢您提供的出色软件包!
    【解决方案2】:

    又快又脏:

    ff<-function(x){
      if(is.numeric(x)){
        b<-by(x==0,df$Group,mean)
        x[df$Group %in% names(b)[b>0.5]]<-0 
      }
      x
    }
    
    data.frame(lapply(df,ff))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-24
      • 2020-06-22
      • 1970-01-01
      • 2015-06-30
      • 2018-11-29
      • 2022-01-19
      • 2019-05-20
      • 1970-01-01
      相关资源
      最近更新 更多