使用循环创建对象,该循环将r中的列表设置为子集 [英] create object with loop that subsets a list in r

查看:27
本文介绍了使用循环创建对象,该循环将r中的列表设置为子集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含90个名称的列表,我希望使用循环将它们划分并包含到对象中。我已经根据模式选择了列表的名称,但是我不确定如何循环来创建对象名称。我以前尝试过使用assign()函数,但它创建的是值(在反号`内),而不是对象。谢谢!

这个列表有90个名字,每个样本名称重复5次,所以基本上我总共有18个样本,每个样本有5个文件。我想为每个样本创建一个对象,其中包含与该样本相对应的名称列表,因此该列表包含5个项目。因此,我希望创建一个循环,而不是复制粘贴函数(sample.1=sample.names.flimtions[grep(";sample1_";,sample.names.flimtions)])18次。我希望这有意义?

#list
>sample.names.dilutions
> length(sample.names.dilutions)
[1] 90

#names in list
> sample.names.dilutions[1:20]
 [1] "New AS Plate 21_AS Plate_Sample 1_100.fcs"  "New AS Plate 21_AS Plate_Sample 1_25.fcs"  
 [3] "New AS Plate 21_AS Plate_Sample 1_250.fcs"  "New AS Plate 21_AS Plate_Sample 1_50.fcs"  
 [5] "New AS Plate 21_AS Plate_Sample 1_500.fcs"  "New AS Plate 21_AS Plate_Sample 10_100.fcs"
 [7] "New AS Plate 21_AS Plate_Sample 10_25.fcs"  "New AS Plate 21_AS Plate_Sample 10_250.fcs"
 [9] "New AS Plate 21_AS Plate_Sample 10_50.fcs"  "New AS Plate 21_AS Plate_Sample 10_500.fcs"
[11] "New AS Plate 21_AS Plate_Sample 11_100.fcs" "New AS Plate 21_AS Plate_Sample 11_25.fcs" 
[13] "New AS Plate 21_AS Plate_Sample 11_250.fcs" "New AS Plate 21_AS Plate_Sample 11_50.fcs" 
[15] "New AS Plate 21_AS Plate_Sample 11_500.fcs" "New AS Plate 21_AS Plate_Sample 12_100.fcs"
[17] "New AS Plate 21_AS Plate_Sample 12_25.fcs"  "New AS Plate 21_AS Plate_Sample 12_250.fcs"
[19] "New AS Plate 21_AS Plate_Sample 12_50.fcs"  "New AS Plate 21_AS Plate_Sample 12_500.fcs"

#function i want to create with loop
> sample.1 = sample.names.dilutions[grep("Sample 1_", sample.names.dilutions)]
> length(sample.1)
[1] 5
> sample.1
[1] "New AS Plate 21_AS Plate_Sample 1_100.fcs" "New AS Plate 21_AS Plate_Sample 1_25.fcs" 
[3] "New AS Plate 21_AS Plate_Sample 1_250.fcs" "New AS Plate 21_AS Plate_Sample 1_50.fcs" 
[5] "New AS Plate 21_AS Plate_Sample 1_500.fcs"

> #i have 18 different samples and want to assign value and subset according to sample name
> for(i in 1:18) {
+   print(sample.names[i], quote=FALSE) = sample.names.dilutions[grep(paste0("Sample ",i,"_"), sample.names.dilutions)]}

Error in print(sample.names[i], FALSE) <- sample.names.dilutions[grep(paste0("Sample ",  : 
  could not find function "print<-"

推荐答案

我想我现在明白了;感谢您在评论中澄清您的问题。如果我遗漏了什么,或者您有任何问题,请让我知道。

术语,快速

我相信您有兴趣根据每个元素中的模式将字符串向量拆分成多个较短的字符串向量。列表只是向量的向量。

g是由20个字符串元素组成的向量(请参阅下面的数据代码块)。

is.vector(g)
#> [1] TRUE

这里的列表只包含一个向量。

str(list(g))
#> List of 1
#>  $ : chr [1:20] "New AS Plate 21_AS Plate_Sample 12_50.fcs" "New AS Plate 21_AS Plate_Sample 1_100.fcs" "New AS Plate 21_AS Plate_Sample 1_25.fcs" "New AS Plate 21_AS Plate_Sample 1_250.fcs" ...

现在转到问题.

在您的问题中,您特别询问了如何使用assign()。虽然使用assign()比较方便,但[通常不推荐][1]。但有时候你得做你该做的事,这没什么可羞耻的。以下是您如何手动使用它,一次在一个组上使用(如您的问题中所示)。

# Using assign() one group at a time
h <- g[grep("Sample 1_", g)]
assign(x = "sample_1_group", value = h)

在for循环中使用assign()非常简单(看起来也很合乎逻辑)。

定义for循环的第一步是定义循环将是什么,或者换句话说,在循环的每次迭代期间将发生什么变化。在您的情况下,我们正在寻找一个定义您的组的数字。我们可以手动或以编程方式定义这些数字的向量。

# Define groups manually
ids <- c(12,1,10,11)
ids
#> [1] 12  1 10 11

# Pattern match groups
all_ids <- gsub(pattern = ".*Sample (\d+).*", replacement = "\1", x = g)
all_ids
#>  [1] "12" "1"  "1"  "1"  "1"  "1"  "10" "10" "10" "10" "10" "11" "11" "11" "11"
#> [16] "11" "12" "12" "12" "12"
ids <- unique(all_ids)
ids
#> [1] "12" "1"  "10" "11"

知道要循环的内容之后,我们可以在中定义循环的结构和函数。paste0()可以成为这里的主力。下面的循环迭代ID(一次一个ID),在g中查找匹配的字符串,并将它们作为向量写入您的环境。因为我们使用的是assign(),所以我们希望在循环的每次迭代之后都会在我们的环境中出现一个新的向量。

# For-loop with assign
for(i in ids){
  a <- paste0("Sample ", i, "_")
  h <- g[grep(a, g)]
  h_name <- paste0("sample_", i, "_group")
  assign(x = h_name, value = h)
}

这在技术上是可行的,但不是最好的。您可能会发现,使用列表(向量的向量)来存储来自for循环的信息实际上更为方便。编程速度很快,没有一堆新对象挤满了你的工作区,上面那个链接中所有可怕的东西(并不是真的)都不会成为问题。您可以这样做:

# Save the results of a for-loop in a list!
# First, make a blank list to hold the results
results <- list()
for(i in ids){
  a <- paste0("Sample ", i, "_")
  h <- g[grep(a, g)]
  h_name <- paste0("sample_", i, "_group")
  results[[h_name]] <- h
}
results
#> $sample_12_group
#> [1] "New AS Plate 21_AS Plate_Sample 12_50.fcs" 
#> [2] "New AS Plate 21_AS Plate_Sample 12_100.fcs"
#> [3] "New AS Plate 21_AS Plate_Sample 12_25.fcs" 
#> [4] "New AS Plate 21_AS Plate_Sample 12_250.fcs"
#> [5] "New AS Plate 21_AS Plate_Sample 12_500.fcs"
#> 
#> $sample_1_group
#> [1] "New AS Plate 21_AS Plate_Sample 1_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 1_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 1_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 1_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 1_500.fcs"
#> 
#> $sample_10_group
#> [1] "New AS Plate 21_AS Plate_Sample 10_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 10_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 10_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 10_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 10_500.fcs"
#> 
#> $sample_11_group
#> [1] "New AS Plate 21_AS Plate_Sample 11_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 11_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 11_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 11_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 11_500.fcs"

额外学分

for-循环很棒:很容易看到它们内部的情况,很容易在其中进行大量数据处理,而且它们的执行速度通常相当快。但有时都是关于速度。R是矢量化的([老实说,我不太清楚这意味着什么][2]此外,它还可以同时进行多个计算),但是for循环不能很好地利用这一点。apply()矢量化函数系列可以做到这一点,在可能还使用for循环的情况下,它们通常很容易实现。以下是如何处理数据的方法:

# Vectorized
lapply(ids, function(i) g[grep(paste0("Sample ", i, "_"), g)])
#> [[1]]
#> [1] "New AS Plate 21_AS Plate_Sample 12_50.fcs" 
#> [2] "New AS Plate 21_AS Plate_Sample 12_100.fcs"
#> [3] "New AS Plate 21_AS Plate_Sample 12_25.fcs" 
#> [4] "New AS Plate 21_AS Plate_Sample 12_250.fcs"
#> [5] "New AS Plate 21_AS Plate_Sample 12_500.fcs"
#> 
#> [[2]]
#> [1] "New AS Plate 21_AS Plate_Sample 1_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 1_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 1_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 1_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 1_500.fcs"
#> 
#> [[3]]
#> [1] "New AS Plate 21_AS Plate_Sample 10_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 10_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 10_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 10_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 10_500.fcs"
#> 
#> [[4]]
#> [1] "New AS Plate 21_AS Plate_Sample 11_100.fcs"
#> [2] "New AS Plate 21_AS Plate_Sample 11_25.fcs" 
#> [3] "New AS Plate 21_AS Plate_Sample 11_250.fcs"
#> [4] "New AS Plate 21_AS Plate_Sample 11_50.fcs" 
#> [5] "New AS Plate 21_AS Plate_Sample 11_500.fcs"
Created on 2021-10-14 by the reprex package (v2.0.1)

数据:

g <- c("New AS Plate 21_AS Plate_Sample 12_50.fcs", 
       "New AS Plate 21_AS Plate_Sample 1_100.fcs",
       "New AS Plate 21_AS Plate_Sample 1_25.fcs", 
       "New AS Plate 21_AS Plate_Sample 1_250.fcs",
       "New AS Plate 21_AS Plate_Sample 1_50.fcs",
       "New AS Plate 21_AS Plate_Sample 1_500.fcs",
       "New AS Plate 21_AS Plate_Sample 10_100.fcs",
       "New AS Plate 21_AS Plate_Sample 10_25.fcs",
       "New AS Plate 21_AS Plate_Sample 10_250.fcs",
       "New AS Plate 21_AS Plate_Sample 10_50.fcs",
       "New AS Plate 21_AS Plate_Sample 10_500.fcs",
       "New AS Plate 21_AS Plate_Sample 11_100.fcs",
       "New AS Plate 21_AS Plate_Sample 11_25.fcs",
       "New AS Plate 21_AS Plate_Sample 11_250.fcs",
       "New AS Plate 21_AS Plate_Sample 11_50.fcs",
       "New AS Plate 21_AS Plate_Sample 11_500.fcs",
       "New AS Plate 21_AS Plate_Sample 12_100.fcs",
       "New AS Plate 21_AS Plate_Sample 12_25.fcs",
       "New AS Plate 21_AS Plate_Sample 12_250.fcs",
       "New AS Plate 21_AS Plate_Sample 12_500.fcs")

[1]:Why is using assign bad?) [2]:How do I know a function or an operation in R is vectorized?

这篇关于使用循环创建对象,该循环将r中的列表设置为子集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆