有两个for循环用(i,j)创建一个列表,其中外部循环不会覆盖内部

时间:2016-10-12 23:31:48

标签: r list loops for-loop lapply

我试图在R中处理lapply和循环。我需要将具有任意列名的矩阵中的每一列重命名为有意义的列。结果应该是这样的:

wages.seg.mean.1996 <- rnorm(4)
wages.seg.var.1996 <- rnorm(4)
wages.seg.sd.1996 <- rnorm(4)
wages.seg.min.1996 <- rnorm(4)
wages.seg.max.1996 <- rnorm(4)
wages.seg.total.1996 <- rnorm(4)
wages.seg.mean.1997 <- rnorm(4)
wages.seg.var.1997 <- rnorm(4)
wages.seg.sd.1997 <- rnorm(4)
wages.seg.min.1997 <- rnorm(4)
wages.seg.max.1997 <- rnorm(4)
wages.seg.total.1997 <- rnorm(4)
df <-  data.frame(wages.seg.mean.1996,wages.seg.var.1996,wages.seg.sd.1996,wages.seg.min.1996,wages.seg.max.1996,wages.seg.total.1996,wages.seg.mean.1997,wages.seg.var.1997,wages.seg.sd.1997,wages.seg.min.1997,wages.seg.max.1997,wages.seg.total.1997)

我知道变量是如何排序的,所以我只需要一个包含正确顺序的所有新名称的列表,然后我可以这样做:

colnames(df) <- wages.list[]  
df <- tbl_df(df)

在我的实际数据中,年份是1996 - 2009年,但我想这个例子不需要超过两年。 我试过这样的,但因为第二个循环是嵌套的,我最后会在去年覆盖其他循环:

wages.seg.list <- NULL 
wages.seg.list <-  list()
 for (i in 1996:1997)  {
    for (j in seq(1,12,6)) {
wages.seg.list[[j]] <-   paste0("wages.seg.mean.",i)
wages.seg.list[[j+1]]   <-   paste0("wages.seg.var.",i)
wages.seg.list[[j+2]]   <-   paste0("wages.seg.sd.",i)
wages.seg.list[[j+3]]   <-   paste0("wages.seg.min.",i)
wages.seg.list[[j+4]]   <-   paste0("wages.seg.max.",i)
wages.seg.list[[j+5]]   <-   paste0("wages.seg.total.",i)
    }
}

所以你看我如何尝试同时改变列表中的位置和变量的名称。当然,我可以手工做到这一点,但我想了解如何做这样的事情的逻辑。如果你能帮助我做到这一点,我将不胜感激。

了Emil

1 个答案:

答案 0 :(得分:1)

这会做你想要的吗?

你说你想知道更多关于如何在R中做循环,但事实恰恰相反。它显示了如何避免循环,这是R的优势之一。 R的向量化意味着要有效地使用R,您必须对其他语言有所不同。你必须花更少的精力告诉电脑&#34;如何&#34;做事,专注于&#34;什么&#34;你想实现。

编辑:更加向量化的解决方案。

yearly.name.template <- c(
  "wages.seg.mean.", 
  "wages.seg.var.",
  "wages.seg.sd.",
  "wages.seg.min.",
  "wages.seg.max.",
  "wages.seg.total."
)


# create the names for your list titles.
all.names.df <- merge(yearly.name.template, 1996:1997, all=TRUE)

# apply(x,1,FUN,...) works row-wise on the data frame or matrix.
# 'collapse' is an argument to 'paste0' to merge the entire row.
all.names <- apply(all.names.df, 1, paste0, collapse="")

# now create a list of blank entries, one entry per list title.
wages.seg.list <- vector("list", length(all.names))

# and push the names in.
names(wages.seg.list) <- all.names