【问题标题】:Split the dataframe into subset dataframes and naming them on-the-fly (for loop)将数据帧拆分为子数据帧并动态命名它们(for循环)
【发布时间】:2012-07-23 04:52:09
【问题描述】:

我在一个数据框中有 9880 条记录,我试图将它分成 9 组,每组 1000 条,最后一组将有 880 条记录,并相应地命名它们。我对 1-9 组使用了 for-loop,但对最后 880 条记录手动使用,但我相信有更好的方法来实现这一点,

library(sqldf)
for (i in 0:8)
{
assign(paste("test",i,sep="_"),as.data.frame(final_9880[((1000*i)+1):(1000*(i+1)),   (1:53)]))
}
test_9<- num_final_9880[9001:9880,1:53]

也无法将所有部分附加到一个 for 循环中!

#append all parts
all_9880<-rbind(test_0,test_1,test_2,test_3,test_4,test_5,test_6,test_7,test_8,test_9)

感谢任何帮助,谢谢!

【问题讨论】:

  • 让我直说。您正在尝试将每 1000 个观察值移动到单个对象(test_1、test_2 ...),然后最后将其 rbind 结合在一起?你不会得到和刚开始时一样的对象吗?

标签: r for-loop split


【解决方案1】:

this 解决方案的一个小变化

ls <- split(final_9880, rep(0:9, each = 1000, length.out = 9880))  # edited to Roman's suggestion
for(i in 1:10) assign(paste("test",i,sep="_"), ls[[i]])

您的绑定命令应该可以工作。

编辑

如果您有很多数据帧,您可以使用 parse-eval 组合。我使用包gsubfn 以提高可读性。

library(gsubfn)
nms <- paste("test", 1:10, sep="_", collapse=",")
eval(fn$parse(text='do.call(rbind, list($nms))'))

这是如何工作的?首先,我创建一个包含逗号分隔的数据框列表的字符串

> paste("test", 1:10, sep="_", collapse=",")
[1] "test_1,test_2,test_3,test_4,test_5,test_6,test_7,test_8,test_9,test_10"

然后我用这个字符串来构造列表

list(test_1,test_2,test_3,test_4,test_5,test_6,test_7,test_8,test_9,test_10)

parseeval 与字符串插值一起使用。

eval(fn$parse(text='list($nms)'))

字符串插值是通过parse的前缀fn$实现的,其作用是截取$nms并用变量nms中包含的字符串替换。解析和评估字符串"list($mns)" 创建所需的列表。在解决方案中,rbind 包含在 parse-eval 组合中。

编辑 2

您可以收集所有具有某种模式的变量,将它们放在一个列表中并按行绑定它们。

do.call("rbind", sapply(ls(pattern = "test_"), get, simplify = FALSE))

ls 查找模式为“test_”的所有变量

sapply 检索所有这些变量并将它们存储在一个列表中

do.call 按行展平列表。

【讨论】:

  • 谢谢!我知道 rbind 有效..但是假设文件有数百万条记录,我将它分成 100 个部分...单独 rbind 会很烦人,有没有办法使用 for 循环或其他东西附加它们?
  • 为什么还要绑定它们?它肯定会返回原始数据吗?
  • mnel:实际上正在处理数据拆分,然后附加它@RYogi:是的,它做到了。非常感谢大家:)
  • @RYogi:我真的很想为你的答案投票,但#reps 限制了我 :) 感谢后端编辑
  • 你可以做rep(0:9, each = 1000, length.out = 9880)
【解决方案2】:

不需要for循环——使用split

data <- data.frame(a = 1:9880, b = sample(letters, 9880, replace = TRUE))

splitter <- (data$a-1) %/% 1000

.list <- split(data, splitter)

lapply(0:9, function(i){
  assign(paste('test',i,sep='_'), .list[[(i+1)]], envir = .GlobalEnv)
  return(invisible())
})

all_9880<-rbind(test_0,test_1,test_2,test_3,test_4,test_5,test_6,test_7,test_8,test_9)

identical(all_9880,data)
## [1] TRUE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2021-09-26
    • 2019-07-29
    • 2023-01-19
    • 2017-08-16
    相关资源
    最近更新 更多