2016-12-29 2 views
0

Я работаю в R с 10 списками (files1, files2, files3, ... files10). Каждый список содержит несколько фреймов данных.R - использование названий списков в петле

Теперь я хочу извлечь некоторые значения из каждого кадра данных в каждом списке.

Я собирался использовать для цикла

nt = c("A", "C", "G", "T") 
for (i in files1) { 
    for (j in nt) { 
     name = paste(j, i, sep = "-") # here I want as output name = "files1-A". However this doesn't work. How can I get the name of the list "files1"? 
     colname = paste("percentage", j, sep = "") # here I was as output colname = percentageA. This works 
     assign(name, unlist(lapply(i, function(x) x[here I want to use the column with the name "percentageA", so 'colname'][x$position==1000]))) 
    } 
} 

Итак, у меня есть проблемы с использованием имен списков и присвоения их переменным.

Я знаю только цикл через первый список, но можно ли сразу пропустить все мои списки?

Другими словами: как я могу поместить код ниже в цикл for?

A_files1 = unlist(lapply(files1, function(x) x$percentageA[x$position==1000])) 
C_files1 = unlist(lapply(files1, function(x) x$percentageC[x$position==1000])) 
G_files1 = unlist(lapply(files1, function(x) x$percentageG[x$position==1000])) 
T_files1 = unlist(lapply(files1, function(x) x$percentageT[x$position==1000])) 

A_files2 = unlist(lapply(files2, function(x) x$percentageA[x$position==1000])) 
C_files2 = unlist(lapply(files2, function(x) x$percentageC[x$position==1000])) 
G_files2 = unlist(lapply(files2, function(x) x$percentageG[x$position==1000])) 
T_files2 = unlist(lapply(files2, function(x) x$percentageT[x$position==1000])) 

.... 

A_files10 = unlist(lapply(files10, function(x) x$percentageA[x$position==1000])) 
C_files10 = unlist(lapply(files10, function(x) x$percentageC[x$position==1000])) 
G_files10 = unlist(lapply(files10, function(x) x$percentageG[x$position==1000])) 
T_files10 = unlist(lapply(files10, function(x) x$percentageT[x$position==1000])) 
+0

does 'names (fileS1)' return 'NULL'? –

+0

@ joel.wilson: yes it – user1987607

+0

Было бы здорово разместить образцы данных, например, 2-3 файла, чтобы иметь рабочий пример. См. [Как сделать воспроизводимый пример] (http: // stackoverflow.ком/вопросы/5963269/как к Make-A-пра-р-воспроизводимая-пример/5965451 # 5965451). В общем, для чтения нескольких файлов я создаю функцию (variable1, variable2), которая возвращает кадр данных из одного файла. Затем я использую пакет 'dplyr' с' group_by (variable1, variable2) '' do (myfunction (. $ Variable1,. $ Variable2)) 'для чтения нескольких файлов. это здорово, чтобы получить все данные в одном кадре данных. –

ответ

0

Для того, чтобы ответить на ваш вопрос, я создать фальшивый список содержащие dataframes:

n = data.frame(andrea=c(1983, 11, 8),paja=c(1985, 4, 3)) 
s = data.frame(col1=c("aa", "bb", "cc", "dd", "ee")) 
b = data.frame(col1=c(TRUE, FALSE, TRUE, FALSE, FALSE)) 
x = list(n, s, b, 3) # x contains copies of n, s, b 
names(x) <- c("dataframe1","dataframe2","dataframe3","dataframe4") 
files1 = x 

Теперь, войдя в том, что происходит в цикле:

i = files1 
j = "A" 

Если вы хотите, имена ваших фреймов данных с педикой, содержащейся в nt (в данном случае это nt = "A"), вы должны использовать имена (i):

name_wrong = paste(j, i, sep = "-") 
name  = paste(names(i),j,sep = "-") 

Так вы получите:

> name 
[1] "dataframe1-A" "dataframe2-A" "dataframe3-A" "dataframe4-A" 

Я надеюсь, что это то, что вам нужно.

+0

Это не совсем то, что я хочу. Я не хочу назвать все мои данные, я просто хочу использовать имя моих списков. – user1987607

+1

Как насчет того, чтобы вы поместили все свои списки в список: 'biglist <- list (files1 = files1)' 'names (biglist)' вернет вам '[1]" files1 "'. –

0

Я думаю, что эти данные будут легче манипулировать, если вы сгладите структуру данных. Вместо 10 списков кадров данных вы можете использовать один единственный фрейм данных со всеми наблюдениями, индексированными их именами и именами файлов.

Генерация данных выборки и использовать код от вопроса

Упрощенные данные только с 10 или 11 баллов по каждому пункту Я полагаю, элементы списка имеют разное количество линий?

files1 <- list(item1 = data.frame(position = 1:10, 
            percentageA = 1:10/10, 
            percentageC = 1:10/10, 
            percentageG = 1:10/10, 
            percentageT = 1:10/10), 
       item2 = data.frame(position = 1:11, 
            percentageA = 1:11/20, 
            percentageC = 1:11/20, 
            percentageG = 1:11/20, 
            percentageT = 1:11/20)) 
str(file) 

# Select the 9th position using your code 
A_files1 = unlist(lapply(files1, function(x) x$percentageA[x$position==9])) 
C_files1 = unlist(lapply(files1, function(x) x$percentageC[x$position==9])) 
G_files1 = unlist(lapply(files1, function(x) x$percentageG[x$position==9])) 
T_files1 = unlist(lapply(files1, function(x) x$percentageT[x$position==9])) 

Свести список dataframes в один dataframe

# Add name to each data frame 
# Inspired by this answer 
# http://stackoverflow.com/a/18434780/2641825 


# For information l[1] creates a single list item 
# l[[1]] extracts the data frame from the list 
#' @param i index 
#' @param listoffiles list of data frames 
addname <- function(i, listoffiles){ 
    dtf <- listoffiles[[i]] # Extract the dataframe from the list 
    dtf$name <- names(listoffiles[i]) # Add the name inside the data frame 
    return(dtf) 
} 
# Add the name inside each data frame 
files1 <- lapply(seq_along(files1), addname, files1) 
str(files1) # look at the structure of the list 
files1table <- Reduce(rbind,files1) 

# Get the values of interest with 
files1table$percentageA[files1table$position == 9] 
# [1] 0.90 0.45 

# Get all Letters of interest with 
subset(files1table,position==9) 

# position percentageA percentageC percentageG percentageT name 
# 9   9  0.90  0.90  0.90  0.90 item1 
# 19  9  0.45  0.45  0.45  0.45 item2 

Свести все списки списков dataframes в один dataframe

# Now create anoter list, files2, duplicate just for the sake of the example 
files2 <- files1 
# file1 and file2 both have a name column inside their dataframes already 
# Create a list of list of dataframes 
lolod <- list(files1 = files1, files2 = files2) 
str(lolod) # a list of lists 
# Flatten to a list of dataframes 
# Use sapply to keep names based on this answer http://stackoverflow.com/a/9469981/2641825 
lod <- sapply(lolod, Reduce, f=rbind, simplify = FALSE, USE.NAMES = TRUE) 
# Add the name inside each data frame again 
addfilename <- function(i, listoffiles){ 
    dtf <- listoffiles[[i]] # Extract the dataframe from the list 
    dtf$filename <- names(listoffiles[i]) # Add the name inside the data frame 
    return(dtf) 
} 
lod <- lapply(seq_along(lod), addfilename, lod) 


# Flatten to a dataframe 
d <- Reduce(rbind, lod) 
# Now the data structure is flattened and much easier to deal with 

subset(d,position==9) 
# position percentageA percentageC percentageG percentageT name filename 
# 9   9  0.90  0.90  0.90  0.90 item1 files1 
# 19  9  0.45  0.45  0.45  0.45 item2 files1 
# 30  9  0.90  0.90  0.90  0.90 item1 files2 
# 40  9  0.45  0.45  0.45  0.45 item2 files2 

Этот ответ гораздо больше, чем я ожидал быть. Надеюсь, я тебя не испугал. Вдохновленный tidy data, упрощение структуры данных облегчит вашу работу позже. Это переименование списка сложных списков, вероятно, не было бы необходимым, если бы вы указали имена внутри исходных данных.

Смежные вопросы