如何遍历列表列表,同时基于变量对列表进行子集设置

时间:2019-03-29 11:44:01

标签: r list for-loop

我有一个列表列表,类似于此处给出的玩具示例。我想遍历此列表以返回一个新列表,该列表已根据变量删除了元素。


dput(head(list)):

post_install do |installer|
  installer.pods_project.targets.each do |target|
    # Cache pod does not accept optimization level '-O', causing Bus 10 error. Use '-Osize' or '-Onone'
    if target.name == 'Cache'
      target.build_configurations.each do |config|
        level = '-Osize'
        config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = level
        puts "Set #{target.name} #{config.name} to Optimization Level #{level}"
      end
    end
  end
end

我已经尝试过手动对列表列表进行子设置。一个功能将是更可取的是因为我有多种类型的数据要子集。

1)根据整数对子级别列进行设置

list(FEB_gems = list(GAME1 = structure(list(GAME1_Class = structure(c(2L, 
1L, 5L, 4L, 3L), .Label = c("fighter", "paladin", "rouge", "sorcerer", 
"wizard"), class = "factor"), GAME1_Race = structure(c(3L, 1L, 
4L, 3L, 2L), .Label = c("elf", "gnome", "human", "orc"), class = "factor"), 
GAME1_Alignment = structure(c(4L, 2L, 1L, 5L, 3L), .Label = c("CE", 
"CG", "LG", "NE", "NN"), class = "factor"), GAME1_Level = c(6, 
7, 6, 7, 7), GAME1_Alive = structure(c(1L, 1L, 1L, 1L, 1L
), .Label = "y", class = "factor")), class = "data.frame", row.names = c(NA, 
-5L)), GAME2 = structure(list(GAME2_Class = structure(c(3L, 5L, 
2L, 4L, 1L), .Label = c("bard", "cleric", "fighter", "monk", 
"wizard"), class = "factor"), GAME2_Race = structure(c(2L, 3L, 
2L, 4L, 1L), .Label = c("dwarf", "elf", "half-elf", "human"), class = "factor"), 
GAME2_Alignment = structure(c(4L, 2L, 1L, 5L, 3L), .Label = c("CE", 
"CG", "LG", "NE", "NN"), class = "factor"), GAME2_Level = c(5, 
5, 5, 5, 5), GAME2_Alive = structure(c(1L, 2L, 2L, 2L, 2L
), .Label = c("n", "y"), class = "factor")), class = "data.frame", row.names = c(NA, 
-5L))), MAR_gems = list(GAME3 = structure(list(GAME3_Class = structure(c(2L, 
1L, 5L, 4L, 3L), .Label = c("barbarian", "cleric", "monk", "ranger", 
"warlock"), class = "factor"), GAME3_Race = structure(c(2L, 3L, 
2L, 4L, 1L), .Label = c("dwarf", "elf", "half-elf", "human"), class = "factor"), 
GAME3_Alignment = structure(c(2L, 2L, 1L, 3L, 2L), .Label = c("CE", 
"LG", "LN"), class = "factor"), GAME3_Level = c(1, 1, 1, 
1, 1), GAME3_Alive = structure(c(2L, 2L, 2L, 1L, 2L), .Label = c("n", 
"y"), class = "factor")), class = "data.frame", row.names = c(NA, 
-5L)), GAME4 = structure(list(GAME4_Class = structure(c(2L, 1L, 
5L, 4L, 3L), .Label = c("fighter", "paladin", "rouge", "sorcerer", 
"wizard"), class = "factor"), GAME4_Race = structure(c(2L, 3L, 
 2L, 4L, 1L), .Label = c("dwarf", "elf", "half-elf", "human"), class = "factor"), 
GAME4_Alignment = structure(c(1L, 2L, 1L, 4L, 3L), .Label = c("CE", 
"CG", "LG", "LN"), class = "factor"), GAME4_Level = c(5, 
5, 5, 5, 5), GAME4_Alive = structure(c(1L, 2L, 2L, 2L, 2L
), .Label = c("n", "y"), class = "factor")), class = "data.frame", row.names = c(NA, 
-5L))))

df1:

df1 <- Games.Split[[1]][[1]]
Level <- df1[which(df1[4] > 6),]
Games.Split[[1]][[1]] <- Level

级别:

  GAME1_Class GAME1_Race GAME1_Alignment GAME1_Level GAME1_Alive
1     paladin      human              NE           6           y
2     fighter        elf              CG           7           y
3      wizard        orc              CE           6           y
4    sorcerer      human              NN           7           y
5       rouge      gnome              LG           7           y

2)基于字符串子设置Alive列

 GAME1_Class GAME1_Race GAME1_Alignment GAME1_Level GAME1_Alive
2     fighter        elf              CG           7           y
4    sorcerer      human              NN           7           y
5       rouge      gnome              LG           7           y

df2:

df2 <- Games.Split[[1]][[2]]
Alive <- df2[which(df2[5] == 'y'),]
Games.Split[[1]][[2]] <- Alive

活着:

 GAME2_Class GAME2_Race GAME2_Alignment GAME2_Level GAME2_Alive
1     fighter        elf              NE           5           n
2      wizard   half-elf              CG           5           y
3      cleric        elf              CE           5           y
4        monk      human              NN           5           y
5        bard      dwarf              LG           5           y

但是,我正在努力将其放入for循环中以在整个列表中执行这些子设置任务。

 GAME2_Class GAME2_Race GAME2_Alignment GAME2_Level GAME2_Alive
2      wizard   half-elf              CG           5           y
3      cleric        elf              CE           5           y
4        monk      human              NN           5           y
5        bard      dwarf              LG           5           y

总体而言,一种可以遍历整个列表以提供不再具有已删除元素的新列表的功能/方法。

3 个答案:

答案 0 :(得分:2)

由于您有两个级别的列表来组织数据框,因此这将需要嵌套的列表应用功能(lapply)-与循环相同,但更加整洁。这是一个示例,该示例创建一个基于最大级别(maxLevel)子集游戏列表(gameList)的函数:

listSubset <- function(x, maxLevel){
  lapply(x, function(ls){
    lapply(ls, function(df) df[df[[grep('Level', names(df), value = TRUE)]] < maxLevel, ])
  })
}
listSubset(x = gameList, maxLevel = 6)

输出:

$`FEB_gems`
$`FEB_gems`$`GAME1`
[1] GAME1_Class     GAME1_Race      GAME1_Alignment GAME1_Level     GAME1_Alive    
<0 rows> (or 0-length row.names)

$`FEB_gems`$GAME2
  GAME2_Class GAME2_Race GAME2_Alignment GAME2_Level GAME2_Alive
1     fighter        elf              NE           5           n
2      wizard   half-elf              CG           5           y
3      cleric        elf              CE           5           y
4        monk      human              NN           5           y
5        bard      dwarf              LG           5           y


$MAR_gems
$MAR_gems$`GAME3`
  GAME3_Class GAME3_Race GAME3_Alignment GAME3_Level GAME3_Alive
1      cleric        elf              LG           1           y
2   barbarian   half-elf              LG           1           y
3     warlock        elf              CE           1           y
4      ranger      human              LN           1           n
5        monk      dwarf              LG           1           y

$MAR_gems$GAME4
  GAME4_Class GAME4_Race GAME4_Alignment GAME4_Level GAME4_Alive
1     paladin        elf              CE           5           n
2     fighter   half-elf              CG           5           y
3      wizard        elf              CE           5           y
4    sorcerer      human              LN           5           y
5       rouge      dwarf              LG           5           y

所有功能都在base R中,因此无需安装和学习新软件包。

答案 1 :(得分:1)

如果只有两个嵌套的list,并且需要不同的filter处理条件,请分别对其应用,然后将输出分配回list元素。我们通过list遍历主map,然后应用逻辑条件

library(purrr)
library(dplyr)
lst2 <- map(lst1, ~  {
       .x[[1]] <- .x[[1]] %>%
                       filter_at(4, all_vars(. > 6))
       .x[[2]] <- .x[[2]] %>%
                      filter_at(5, all_vars(. == 'y'))
         .x
    })

答案 2 :(得分:1)

我认为,如果您重组数据,然后使用dplyr的{​​{1}}提取想要的内容(或省略不需要的内容),生活会更轻松。假设您的原始数据称为filter

foo

现在您的数据如下:

# Load libraries
library(dplyr)
library(purrr)

# Remove one list
bar <- unlist(foo, recursive = FALSE)

# Get names of campaigns and games
campaign_games <- data.frame(do.call(rbind, strsplit(names(bar), "\\.")))

# Add campaigns and games numbers to data frames
ls_games <- pmap(list(campaign_games[, 1], campaign_games[, 2], bar), cbind)

# Rename all columns
ls_games <-  lapply(ls_games, function(x){names(x) <- c("Campaign", "Game_n", "Class", "Race", "Alignment", "Level", "Alive"); x})

# Convert to data frame
df <- bind_rows(ls_games)

# Look at result
head(df)

这很容易处理。例如,拉出那些在FEB宝石游戏1中还活着且等级7或更高的宝石。

#   Campaign Game_n    Class  Race Alignment Level Alive
# 1 FEB_gems  GAME1  paladin human        NE     6     y
# 2 FEB_gems  GAME1  fighter   elf        CG     7     y
# 3 FEB_gems  GAME1   wizard   orc        CE     6     y
# 4 FEB_gems  GAME1 sorcerer human        NN     7     y
# 5 FEB_gems  GAME1    rouge gnome        LG     7     y
# 6 FEB_gems  GAME2  fighter   elf        NE     5     n