我有10个不同的对象:a1,a2,... a10。 我需要做的就是对每个变量进行简单的更改。 比如
a1$x <- a1$x + 1
a2$x <- a2$x + 1
...
a10$x <- a10$x + 1
和
a1[,'new_x']<-cumprod(a1$x)
a2[,'new_x']<-cumprod(a2$x)
...
a10[,'new_x']<-cumprod(a10$x)
我想使用&#39;缩小这些代码。环。 我试过了
for(i in 1:10) {
ai[,'new_x'] <- cumprod(ai$x)
}
当然它不起作用。 有没有办法让这项工作?
答案 0 :(得分:1)
这不起作用,因为您无法通过迭代器i
替换名称的一部分来调用对象。如果要迭代,则必须首先将对象分组到一个对象中,如list
或data.frame
。从你的代码我推断a对象是data.frames,所以这里最合乎逻辑的是将它们存储在list
中。
a1 <- data.frame(x = 1:10)
a2 <- data.frame(x = 11:15)
a3 <- data.frame(x = 16:30)
a_list <- list(a1, a2, a3)
for(i in 1:length(a_list)){
a_list[[i]]$x <- a_list[[i]]$x + 1
a_list[[i]]$x_new <- cumsum(a_list[[i]]$x)
}
替代for
循环,您可以在R中使用apply系列,这会产生更清晰的代码。
a_list <- list(a1, a2, a3)
lapply(a_list, function(df) {
df$x <- df$x + 1
df$x_new <- cumsum(df$x)
return(df)
})
如果您的数据帧具有完全相同的结构,则更方便的是将所有数据绑定到一个数据帧,并添加一个id列,该行来自哪个数据帧。然后使用dplyr
对其进行更改
library(dplyr)
a_df <- rbind(a1 %>% mutate(df = 1), a2 %>% mutate(df = 2), a3 %>% mutate(df = 3))
a_df %>% mutate(x = x + 1) %>% group_by(df) %>% mutate(x_new = cumsum(x))
答案 1 :(得分:0)
如果使用eval()
函数读取对象并使用assign()
函数来编写对象,则可以使用循环方法而无需先将对象转换为单个列表或数据框。例如:
a1 <- data.frame(x=1:5)
a2 <- data.frame(x=2:6)
a3 <- data.frame(x=3:7)
for(i in 1:3) {
dfname <- paste0("a", i)
df <- eval(parse(text=dfname))
df$new_x <- cumprod(df$x)
assign(dfname, df)
}
a1