在嵌套for循环中使用grep

时间:2016-04-13 14:41:54

标签: r

我正在尝试自动化其中一个模拟。我有两组数据。一个是患者的主题ID(187行长),另一个是样本ID(3057行长)。我想根据主题对样本ID进行分类。

例如:子ID = ABCD。从受试者获取的样本将是ABCD-0001,ABCD-0002等。

现在我尝试使用grep搜索子ID中的每个元素,看看它是否是样本ID的子集。如果是这样,那么它返回的值可以插入到一个新的向量中,新向量的行由grep返回的值表示[与样本ID中的行号相同],该值与行相同主题ID中的数字

SubID       SampID

ABCD        ABCD-0001
EFGH        ABCD-0002   
IJKL        IJKL-0001
            IJKL-0002
            EFGH-0001
            EFGH-0002
            EFGH-0003

期望输出

Numeric ID
1
1
3
3
2
2
2

我正在使用此代码

j = 1:nrow(SubID)
i = 1:nrow(SampID)

for (val in j)
{
  for(val in i)
{
    if (length(k<-grep(SubID[j,1],SampID[i,1]))>0)
    {
      l=as.numeric(unlist(k))
      Ind[l]=j
    }
  }
}

1 个答案:

答案 0 :(得分:1)

有一些方法可以在不使用for-loop

的情况下解决这个问题

数据:

a = data.frame(subID = c("ab","cd","de"))
b = data.frame(SampID = c("ab-1","ab-2","de-1","de-2","cd-1","cd-2","cd-3"))

> a
  subID
1    ab
2    cd
3    de

> b
  SampID
1   ab-1
2   ab-2
3   de-1
4   de-2
5   cd-1
6   cd-2
7   cd-3

要获得相应的索引,首先要获取前两个元素的子字符串(在我的例子中!如果所有字母都有4个字母,那么你的字符串应该从1到4!)

f = substr(b$SampID,1,2)
b$num = sapply(f,function(x){which(x==a)})

给出了:

> b
  SampID num
1   ab-1   1
2   ab-2   1
3   de-1   3
4   de-2   3
5   cd-1   2
6   cd-2   2
7   cd-3   2

编辑:不同的字母长度

如果a中有不同长度的字母,那么只能使用一个for循环来完成。试试这个

a = data.frame(subID = c("ab","cd","def"))
b = data.frame(SampID = c("ab-1","ab-2","def-1","def-2","cd-1","cd-2","cd-3"))

b$num = 0
for (k in 1:length(a$subID)){
    b$num[grepl( pattern = a$subID[k] , x = b$SampID)] = k
}

在这种情况下循环遍历a的每个元素并使用grepl来确定具有此模式的那些SampID。将循环编号分配给返回true的循环编号。

新结果:

> b
  SampID num
1   ab-1   1
2   ab-2   1
3  def-1   3
4  def-2   3
5   cd-1   2
6   cd-2   2
7   cd-3   2