在for循环中,如何在“ starts_with”引号内插入变量i?

时间:2019-07-07 13:20:16

标签: r dplyr startswith

我有一个很大的数据框,物种在行中,样本在列中。有30个样本,每个样本有12个重复样本。列名是这样写的:sample.S1.01;样品S1.02 .....样品S30.11;样本。S30.12。

我想创建30个新表,每个表包含12个重复项。

我有此命令行,一次可以完美地用于一个示例:

dt<- tab_sp_sum %>%
    select(starts_with("sample.S1."))
assign(paste("tab_sp_1"), dt)

但是当我将它放入for循环中时,它不再起作用。 我认为这是由于变量i包含在starts_with引号中,而且我不知道如何编写。

for (i in 1:30){
  dt<- tab_sp_sum %>%
    select(starts_with("sample.S",i,".", sep=""))
  assign(paste("tab_sp",i,sep="_"), dt)

尽管最后一行效果很好,但是使用正确的名称创建了30个表,但它们为空。

有什么建议吗?

谢谢

2 个答案:

答案 0 :(得分:2)

与其使用assign并将其存储在不同的对象中,不如尝试使用list。使用select创建要paste0的名称,然后使用map创建数据框列表。

library(dplyr)
library(purrr)

df_names <- paste0("sample.S", 1:30, ".")

df1 <- map(df_names, ~tab_sp_sum %>% select(starts_with(.x)))

然后,您可以使用df1[[1]]df1[[2]]访问单个数据帧。


在基数R中,我们可以通过创建正则表达式来选择以lapply开头的列来使用df_names

df1 <- lapply(df_names, function(x) 
             tab_sp_sum[grep(paste0("^", x), names(tab_sp_sum))])

将其与内置iris数据集结合使用

df_names <- c("Sepal", "Petal")
df1 <- map(df_names, ~iris %>% select(starts_with(.x)))

head(df1[[1]])
#  Sepal.Length Sepal.Width
#1          5.1         3.5
#2          4.9         3.0
#3          4.7         3.2
#4          4.6         3.1
#5          5.0         3.6
#6          5.4         3.9

 head(df1[[2]])
#  Petal.Length Petal.Width
#1          1.4         0.2
#2          1.4         0.2
#3          1.3         0.2
#4          1.5         0.2
#5          1.4         0.2
#6          1.7         0.4

答案 1 :(得分:2)

我们可以在split中使用base R

nm1 <- paste(c("Sepal", "Petal"), collapse="|")
nm2 <- grep(nm1, names(iris), value = TRUE)
out <- split.default(iris[nm2], sub("\\..*", "", nm2))
head(out[[1]])
#  Petal.Length Petal.Width
#1          1.4         0.2
#2          1.4         0.2
#3          1.3         0.2
#4          1.5         0.2
#5          1.4         0.2
#6          1.7         0.4

head(out[[2]])
#  Sepal.Length Sepal.Width
#1          5.1         3.5
#2          4.9         3.0
#3          4.7         3.2
#4          4.6         3.1
#5          5.0         3.6
#6          5.4         3.9

或者在tidyverse

iris %>%
     select(nm2) %>%
      split.default(str_remove(nm2, "\\..*"))