子集data.frame并计算频率

时间:2015-05-20 12:14:22

标签: r

我想计算在data.frame的每一行中找到值1和-1的次数

df <-
         Chr     start       end        value.1 value.2  value.3
            1   68580000    68640000     0        1        1
            1   115900000   116260000   NA       -1        1
            1   173500000   173680000   -1       -1        1
            1   173500000   173680000    1        1       -1

expected output <-
      Chr     start       end      value.1 value.2  value.3    freq.1   freq.-1
        1   68580000    68640000     0        1        1          2        0
        1   115900000   116260000    0       -1        1          1        1
        1   173500000   173680000   -1       -1        1          1        2
        1   173500000   173680000    1        1       -1          2        1

4 个答案:

答案 0 :(得分:3)

一种可能性是

df[c("freq.1", "freq.-1")] <- cbind(rowSums(df[4:6] == 1, na.rm = TRUE),
                                    rowSums(df[4:6] == -1, na.rm = TRUE))

答案 1 :(得分:1)

另一种选择,使用table

df[paste("freq", c(1, -1), sep=".")] <- t(apply(df[, 4:6], 1, 
                                          function(x){
                                              x <- factor(x, levels=(-1):1)
                                              return(table(x)[c("1","-1")])
                                          }))

df
#  Chr     start       end value.1 value.2 value.3 freq.1 freq.-1
#1   1  68580000  68640000       0       1       1      2       0
#2   1 115900000 116260000      NA      -1       1      1       1
#3   1 173500000 173680000      -1      -1       1      1       2
#4   1 173500000 173680000       1       1      -1      2       1

数据

df <- structure(list(Chr = c(1L, 1L, 1L, 1L), start = c(68580000L, 
115900000L, 173500000L, 173500000L), end = c(68640000L, 116260000L, 
173680000L, 173680000L), value.1 = c(0L, NA, -1L, 1L), value.2 = c(1L, 
-1L, -1L, 1L), value.3 = c(1L, 1L, 1L, -1L)), .Names = c("Chr", 
"start", "end", "value.1", "value.2", "value.3"), class = "data.frame", row.names = c(NA, 
-4L))

答案 2 :(得分:1)

一个更通用的解决方案,对于任意数量的value.*列,可以更加通用:

ds <- read.table(header=T, text="Chr     start       end        value.1 value.2  value.3
            1   68580000    68640000     0        1        1
            1   115900000   116260000   NA       -1        1
            1   173500000   173680000   -1       -1        1
            1   173500000   173680000    1        1       -1")
ds
x <- mapply(function(...) {c(sum(c(...) == 1, na.rm=T), sum(c(...) == -1, na.rm=T))}, ds$value.1, ds$value.2, ds$value.3)
cbind(ds, freq.1=x[1,],`freq.-1`=x[2,]) 

输出:

  Chr     start       end value.1 value.2 value.3 freq.1 freq.-1
1   1  68580000  68640000       0       1       1      2       0
2   1 115900000 116260000      NA      -1       1      1       1
3   1 173500000 173680000      -1      -1       1      1       2
4   1 173500000 173680000       1       1      -1      2       1

答案 3 :(得分:1)

与David的答案类似,但使用data.table。

library(data.table)
dt = data.table(df)

dt[, `:=`('freq.1' = rowSums(.SD == 1, na.rm=TRUE),
          'freq.-1' = rowSums(.SD == -1, na.rm=TRUE)),
   .SDcols = paste0("value.", 1:3)]