【问题标题】:Loop to perform calculations across rows on specific columns matching a pattern (in data frame)?循环以在与模式匹配的特定列上跨行执行计算(在数据框中)?
【发布时间】:2012-06-22 12:29:26
【问题描述】:

我有一个带有一些布尔值 (1/0) 的数据框,如下所示(抱歉,我不知道如何将其制成智能表)

       Flag1.Sam Flag2.Sam Flag3.Sam Flag1.Ted Flag2.Ted Flag3.Ted
probe1         0         1         0         1         0         0
probe2         0         0         0         0         0         0
probe3         1         0         0         0         0         0
probe4         0         0         0         0         0         0
probe5         1         1         0         1         0         0

我有 64 个样本(Sam/Ted....等),它们位于名为 files 的列表中,即;

files <- c("Sam", "Ted", "Ann", ....) 

我想创建一个列,对每个样本的标志值求和以创建以下内容:

               Sam Ted 
probe1.flagsum   1   1
probe2.flagsum   0   0 
probe3.flagsum   1   0 
probe4.flagsum   0   0
probe5.flagsum   2   1

我对 R 相当陌生,试图在需要了解的基础上学习,但我尝试了以下方法:

for(i in files) {
    FLAGS$i <- cbind(sapply(i, function(y) { 
        #greping columns to filter for one sample
        filter1 <- grep(names(filters), pattern=y)
        #print out the summed values for those columns  
        FLAGS$y <-rowSums(filters[,(filter1)])
    }
}

上面的代码不起作用,我有点迷失方向。

谁能帮我解决这个问题或指出我要使用的命令/工具的正确方向。

谢谢。

【问题讨论】:

  • 请不要以“R:”开头你的问题;这就是标签的用途

标签: r for-loop pattern-matching aggregate reshape


【解决方案1】:

这在基础 R reshape 中很容易实现,尽管使用 reshapereshape2 包可能更直观。

这是基于 R 的解决方案:

# Here's your data in its current form
dat = read.table(header=TRUE, text="Flag1.Sam Flag2.Sam   Flag3.Sam   Flag1.Ted   Flag2.Ted   Flag3.Ted
probe1 0   1   0   1   0   0
probe2 0   0   0   0   0   0
probe3 1   0   0   0   0   0
probe4 0   0   0   0   0   0
probe5 1   1   0   1   0   0")
# Generate an ID row
dat$id = row.names(dat)
# Reshape wide to long
r.dat = reshape(dat, direction="long", 
                timevar="probe", 
                varying=1:6, sep=".")
# Calculate row sums
r.dat$sum = rowSums(r.dat[3:5])
# Reshape back to wide format, dropping what you're not interested in
reshape(r.dat, direction="wide", 
        idvar="id", timevar="probe", 
        drop=3:5)
##                id sum.Sam sum.Ted
## probe1.Sam probe1       1       1
## probe2.Sam probe2       0       0
## probe3.Sam probe3       1       0
## probe4.Sam probe4       0       0
## probe5.Sam probe5       2       1

给猫剥皮的方法不止一种

你也可以创建一个像这样的函数:

myFun = function(data, varnames) {
  temp = vector("list", length(varnames))
  for (i in 1:length(varnames)) {
    temp[[i]] = colSums(t(dat[grep(varnames[i], names(data))]))
    names(temp)[[i]] = varnames[i]
  }
  data.frame(temp)
}

然后,利用您拥有的名称向量:

files = c("Sam", "Ted")
myFun(dat, files)
##        Sam Ted
## probe1   1   1
## probe2   0   0
## probe3   1   0
## probe4   0   0
## probe5   2   1

享受吧!

【讨论】:

  • 谢谢你,当我在示例数据上尝试它时效果很好。我现在要在我相当大的真实数据上运行它。非常感谢详细的回复。
  • 是的,它适用于大型数据集,就像 plannapus 的脚本一样。我似乎没有声望点来投票,但如果有帮助,我已经点击了绿色的勾号。
【解决方案2】:

如果filters 是您的输入矩阵,FLAGS 是您想要的输出矩阵,那么我会(天真地)做这样的事情:

FLAGS <- matrix(0,nrow=nrow(filters),ncol=length(files))
for(i in 1:length(files)){
    grep(files[i],colnames(filters)) -> index
    FLAGS[,i] <- rowSums(filters[,index])
    }
colnames(FLAGS) <- files

【讨论】:

  • 太棒了!这对我的真实数据非常有效。感谢您如此迅速的反应。
【解决方案3】:

假设你的矩阵被称为输入

input <- matrix(rbinom(30, 1, 0.5), ncol = 6)
colnames(input) <- c("F1.S", "F2.S", "F3.S", "F1.T", "F2.T", "F3.T")
rownames(input) <- paste("probe", 1:5, sep = "")
input <- as.data.frame(input)

library(reshape)
input$probe <- rownames(input)
Molten <- melt(input, id.vars = "probe")
Molten$ID <- gsub("^.*\\.", "", levels(Molten$variable))[Molten$variable]
cast(probe ~ ID, data = Molten, fun = "sum")

使用来自 mrdwab 的 dat 框架进行更新

dat = read.table(header=TRUE, text="Flag1.Sam Flag2.Sam   Flag3.Sam   Flag1.Ted   Flag2.Ted   Flag3.Ted
probe1 0   1   0   1   0   0
probe2 0   0   0   0   0   0
probe3 1   0   0   0   0   0
probe4 0   0   0   0   0   0
probe5 1   1   0   1   0   0")

library(reshape)
dat$probe <- rownames(dat)
Molten <- melt(dat, id.vars = "probe")
Molten$ID <- gsub("^.*\\.", "", levels(Molten$variable))[Molten$variable]
cast(probe ~ ID, data = Molten, fun = "sum")

【讨论】:

  • 感谢您的快速回复。我用测试数据尝试了这个,输出不符合我的预期。我正在尝试在每个样本的新列中对每个人/样本的所有标志的值进行总计/求和。对不起,如果我的解释不足。
  • 这很奇怪,因为有了 mrdwab 的数据集,我得到的正是你要求的输出。请注意,我只更改了数据集。
  • 对不起!我会再试一次,也许我做错了什么。
  • 感谢您的建议。我不记得我现在到底做了什么,我想我使用了自己的测试数据(今天不在工作),但我最终得到了一张长表(“Molten”),上面有纵向的信息(我意识到的解释很糟糕。无论如何,正如我所说,我确定我做了一些有趣的事情或者只是错误地复制了一些东西。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 2012-04-29
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多