【问题标题】:R loop assign output to new vectorR循环将输出分配给新向量
【发布时间】:2019-02-09 20:15:47
【问题描述】:

我在 R 中工作,尝试使用 for 循环生成几个不同的向量。

首先,我创建了一个名为 df 的小型可重现示例数据框。

cluster.assignment <- c("1 Unknown", "1 Unknown", "2 Neuron","3 
PBMC","4 Basket")
Value1 <- c("a","b","c","d","e")
Value2 <- c("191","234","178","929","123")
df <- data.frame(cluster.assignment,Value1,Value2)

df

  cluster.assignment Value1 Value2
1          1 Unknown      a    191
2          1 Unknown      b    234
3           2 Neuron      c    178
4             3 PBMC      d    929
5           4 Basket      e    123 . 

接下来,我创建一个名为 clusters 的变量,其中包含我感兴趣的数据集的键。

clusters <- c("1 ","4 ")

这是我尝试使用 for 循环提取 df 中感兴趣的数据的行名。

for (COI in clusters) { 
  name2 <- c(gsub(" ","", paste("Cluster", COI, sep = "_")))
  assign(Cluster_1, name2, envir = parent.frame())
  name2 <- grep(COI, df$cluster.assignment)
}

所需的输出是两个向量,称为Cluster_1Cluster_4

Cluster_1 将包含值 12

Cluster_4 将包含值 5

我似乎不知道如何将COI 变量的名称指定为输出向量的名称。

【问题讨论】:

  • COIclusters的每个元素的值,即先是"1 ",后是"2 "。带空格的数字是一个非常糟糕的变量名称——这真的是您想要的,将 COI 变量的名称指定为输出的名称吗?
  • 在这种情况下是的,因为我正在挖掘其他人生成的现有数据集。

标签: r for-loop assign


【解决方案1】:

我建议不要使用assign。相反,我将创建一个命名列表。 See this answer for a long discussion of why lists are better than sequentially named variables。如果在任何时候,您决定要将列表转换为全局环境中的对象,您可以使用list2env,但这样做可能只会做更多的工作。

## subset the data to the parts we care about, use `split` to separate it
## into a list
subdf = df[grepl(paste(clusters, collapse = "|"), df$cluster.assignment), ]
result = split(subdf, subdf$cluster.assignment, drop = TRUE)
result
# $`1 Unknown`
#   cluster.assignment Value1 Value2
# 1          1 Unknown      a    191
# 2          1 Unknown      b    234
# 
# $`4 Basket`
#   cluster.assignment Value1 Value2
# 5           4 Basket      e    123

## name the list as desired
names(result) = paste("Cluster", trimws(clusters), sep = "_")
result
# $`Cluster_1`
#   cluster.assignment Value1 Value2
# 1          1 Unknown      a    191
# 2          1 Unknown      b    234
# 
# $Cluster_4
#   cluster.assignment Value1 Value2
# 5           4 Basket      e    123

## if only the row names are needed, use lapply
result = lapply(result, row.names)
result
# $`Cluster_1`
# [1] "1" "2"
# 
# $Cluster_4
# [1] "5"

其他一些注意事项 - 我假设您在 clusters 中包含空格,以防止例如 "1" 匹配 "12 foo"。您可以考虑改用正则表达式单词边界"\\b1\\b",因为"1 " 仍将匹配"11 foo""21 bar"。更好的是,您可以使用 strplit 或类似方法创建一个新列,其中只包含您要匹配的数字键。

【讨论】:

  • 天哪,我现在明白为什么空间如此糟糕了。感谢您的建议和非常翔实的回答,我会试一试!
【解决方案2】:

除非您有自己的理由,否则我认为没有必要为此创建 for 循环,但以下代码可以满足您的需求:

library(data.table)
Cluster_1<-df[df$cluster.assignment %like% "1 ", c("Value1", "Value2")]
Cluster_2<-df[df$cluster.assignment %like% "4 ", c("Value1", "Value2")]
View(Cluster_1);View(Cluster_2)

您可以删除或更改 c("Value1", "Value2") 以在最终输出中获得所需的列。

【讨论】:

  • 我应该指定这是一个小型便携式示例。不幸的是,在现实生活中,我需要在数百个不同的 COI 值上重复这一点。因此,需要一个循环来迭代该过程并使其可跨数据集移植。问题的核心实际上是我们如何在 for 循环或其他一些高吞吐量的方式中做到这一点。
猜你喜欢
  • 2016-08-18
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 2021-02-26
  • 2016-03-02
相关资源
最近更新 更多