【发布时间】:2015-06-10 12:04:16
【问题描述】:
我的问题可能很简单,但我认为我的代码肯定可以改进。现在它是两个 for 循环,但我确信有一种方法可以在一个循环中完成我需要的操作,因为我一生都看不到它是什么。
搜索 Stack 后,我发现 this 来自 Ananda 的出色答案,他能够使用 lapply 和 for-loop 方法提取列并将其保持在一个范围内。但是,我的数据结构妨碍了我,因为我希望能够选择要删除的特定列。我的数据结构如下所示:
1 AAAT_1 1 GROUP **** 1 -13.70 0
2 AAAT_2 51 GROUP **** 1 -9.21 0
3 AAAT_3 101 GROUP **** 1 -7.60 0
4 AAAT_4 151 GROUP **** 1 -6.28 0
它是从一些对接软件中提取的,我想保留的唯一列是 2(例如 AAAT_1)和 7(例如 -13.70)。我以前做的代码,两个for循环:
for (i in 1:length(temp)) {
assign(temp[i], get(temp[i])[2:7])
}
....保留第 2-7 列的数据,后跟:
for (i in 1:length(temp)) {
assign(temp[i], get(temp[i])[-2:-5])
}
....删除我不需要的其余列,其中 temp[i] 只是循环所作用的数据帧列表。
所以,如您所见,这只是两个循环执行类似操作。当然有一种方法可以选择特定的列来保留/删除并在一个循环/lapply 语句中完成所有操作?在get 语句中尝试[2,7] 之类的东西不起作用,似乎只保留第7 列,而是将每个数据框转换为“值”。我不确定发生了什么,所以任何见解都会很棒,但是,无论哪种方式,如果有人可以将这个双循环解决方案变成一个,我将不胜感激。绝对觉得我错过了一些非常简单/明显的东西。
干杯。
编辑:已经考虑到下面的矢量化解决方案来代替执行以下操作。原始导入数据的名称以 F0001、F0002 等开头,因此使用了创建初始 list 的模式。
lst <- mget(ls(pattern='^F\\d+'))
lst <- lapply(lst, "[", TRUE, c("V2","V7") )
lst <- lapply(seq_along(lst),
function(i,x) {assign(paste0(temp[i]),x[[i]], envir=.GlobalEnv)},
x=lst)
我知道循环在 R 中的名声很差,这对我作为 CPP 程序员来说是一个自然的解决方案,但是嗯,这要快得多。最初,other example 的唯一缺点是assign 命令在原始导入数据文件列表不存在时将一个字母粘贴到顺序为 1、2、3、....、n 的每个创建的表中。 t 完全按数字顺序(即 1、2、3、5、6、10 等),所以这并没有保留该顺序。所以我不得不使用文件列表(我们的老朋友temp)来正确命名它们。次要的事情,代码不比两个循环短多少,但肯定更快。
因此,简而言之,以上三行将所有导入的原始数据添加到列表中,仅保留我需要的列,然后将列表拆分为单独的数据框,同时保留正确的名称。为帮助干杯!
【问题讨论】:
-
你为什么不在你提到的问答中使用the (accepted) answer provided by @BondedDust?