R:从多个数据帧中删除列的for循环解决方案

时间:2015-06-10 12:04:16

标签: r loops

我的问题可能很简单,但我认为我的代码肯定可以改进。现在它是两个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语句中完成所有操作?在[2,7]语句中尝试get之类的内容并不起作用,似乎只保留第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粘贴了一个字母到每个创建的表中数据文件完全不是按数字顺序排列的(即1,2,3,5,6,10,......等),所以这并没有保留这个顺序。所以我必须使用文件列表(我们的老朋友temp)来正确命名它们。小问题和代码并不比两个循环短得多,但它肯定更快。

因此,简而言之,上面三行将所有导入的原始数据添加到列表中,只保留我需要的列,然后将列表拆分为单独的数据帧,同时保留正确的名称。干杯求救!

2 个答案:

答案 0 :(得分:0)

如果您有数据框,则使用

索引行和列
data.frame[row, column]

因此,data.frame[2,7])将为您提供第7列中第2行的值。我猜你在找

temp <- temp[, c(2,7)]

或者,如果temp是数据框列表

temp <- lapply(temp, function(x) x[, c(2,7)])

因此,如果要使用数字向量作为列索引或行索引,请使用c(...)创建此向量。如果我理解你的例子,如果使用lapply,则不需要任何循环命令。

答案 1 :(得分:0)

static void Main(string[] args) { var unsortedList = new List<string>() { "10 dog", "53 cow", "2 crow", "29 horse", "12 rabbit", "107 frog", "35 cat", "7 dragon" }; var sortedList = new SortedList<int, string>((int)unsortedList.Count); foreach(var entry in unsortedList) { string[] frags = entry.Split(' '); if(frags.Length != 2) { throw new FormatException(); } int count = Convert.ToInt32(frags[0]); string name = frags[1]; sortedList.Add(count, name); } Console.WriteLine("UNSORTED:"); unsortedList.ForEach(Console.WriteLine); Console.WriteLine(); Console.WriteLine("SORTED:"); foreach(var entry in sortedList) { Console.WriteLine(entry.Key + " " + entry.Value); } Console.WriteLine(); Console.ReadKey(); } 循环?也许我错过了一些东西,但为什么不使用@Daniel提出的解决方案或像这样的for方法。

dplyr

这里是代码:

data
  V1     V2  V3    V4   V5 V6     V7 V8
1  1 AAAT_1   1 GROUP ****  1 -13.70  0
2  2 AAAT_2  51 GROUP ****  1  -9.21  0
3  3 AAAT_3 101 GROUP ****  1  -7.60  0
4  4 AAAT_4 151 GROUP ****  1  -6.28  0