简体   繁体   English

R:按列拆分列表并转换为新数据

[英]R: Split list by columns and convert into new data.frames

I have the following sample data in a list called data 我在名为data的列表中有以下示例data

data <-    structure(list(`1.1` = structure(list(id = structure(1, .Dim = c(1L, 
    1L)), Sample = structure("Test1", .Dim = c(1L, 1L)), Add = structure("T", .Dim = c(1L, 
    1L))), .Names = c("id", "Sample", "Add")), `2.1` = structure(list(
        id = structure(5, .Dim = c(1L, 1L)), Sample = structure("Test2", .Dim = c(1L, 
        1L)), Add = structure("A", .Dim = c(1L, 1L))), .Names = c("id", 
    "Sample", "Add")), `3.1` = structure(list(id = structure(7, .Dim = c(1L, 
    1L)), Sample = structure("Test3", .Dim = c(1L, 1L)), Add = structure("D", .Dim = c(1L, 
    1L))), .Names = c("id", "Sample", "Add")), `4.1` = structure(list(
        id = structure(12, .Dim = c(1L, 1L)), Sample = structure("Test4", .Dim = c(1L, 
        1L)), Add = structure("Z", .Dim = c(1L, 1L))), .Names = c("id", 
    "Sample", "Add")), `5.1` = structure(list(id = structure(17, .Dim = c(1L, 
    1L)), Sample = structure("Test12", .Dim = c(1L, 1L)), Add = structure("E", .Dim = c(1L, 
    1L))), .Names = c("id", "Sample", "Add"))), .Names = c("1.1", 
    "2.1", "3.1", "4.1", "5.1"), row.names = c("id", "Sample", "Add"
    ), class = "data.frame")

It looks like this: 看起来像这样:

 data
         1.1   2.1   3.1   4.1    5.1
id         1     5     7    12     17
Sample Test1 Test2 Test3 Test4 Test12
Add        T     A     D     Z      E

How could I split this list by column into several data.frames based on the ID number? 如何根据ID号将此列按列分成几个data.frame? Eg that a data.frame with name data.ID1 and a data.frame with name data.ID5 and a data.frame with name data.ID 7 etc. is created (see example below)? 例如,创建了一个名称为data.ID1的data.frame和名称为data.ID5的data.frame和名称为data.ID 7的data.frame等(请参见下面的示例)? The name of the data.frame should be the same as the ID number. data.frame的名称应与ID号相同。 My list contains about 700 different IDs and data... 我的清单包含大约700个不同的ID和数据...

data.ID1
id      1
Sample  Test1
Add     T

data.ID5
id      5
Sample  Test2
Add     A

data.ID7
id      7
Sample  Test3
Add     D

and so on... 等等...

Here's a possible solution: 这是一个可能的解决方案:

lst <- lapply(1:ncol(data),function(c) return(data[,c,drop=F]))
names(lst) <- lapply(data,function(col) return(paste0('data.ID',col$id)))

# here you have data.ID1, data.ID2 etc inside a lst, 
# you can have access to them simply using: lst$data.ID1, lst$data.ID2 etc.
# but if you REALLY want to add these variables in the environment, 
# continue to the next loop

for(nm in names(lst)){
  assign(nm,lst[[nm]])
}

Please, note that is preferred not to use assign since as stated in the comment above, you have all you need inside the list object "lst"... but maybe you need to do it for a valid reason ;) 请注意,最好不要使用assign,因为如上面的注释所述,您在列表对象“ lst”中拥有了所有需要的东西……但是也许出于正当的理由需要这样做;)

Here is a solution close enough, try 这是一个足够接近的解决方案,请尝试

coln <- lapply(data[1,],as.character)
colnames(data) <- paste(rep("data.TD",ncol(data)),coln,sep="")
attach(data)

Then whenever you need to call a certain column by the data id, you do: 然后,每当需要通过数据ID调用某个列时,您都可以执行以下操作:

data.frame(data.TD7)

Output: 输出:

  id Sample Add
1  7  Test3   D

Or you can transpose it using t(data.frame(data.TD7)) 或者您可以使用t(data.frame(data.TD7))转置它

I think these three lines will solve your problem: 我认为这三行将解决您的问题:

newdata <- apply(data, 2, function(x) { y = as.data.frame(x=unlist(x)) })
newname <- paste("data.ID", unlist(data[1, ]), sep="")
names(newdata) <- newname
newdata

new data is a list containing the desired data frames 新数据是包含所需数据帧的列表

data <- structure(list(
  `1.1` = structure(list(id = structure(1, .Dim = c(1L, 1L)),
                         Sample = structure("Test1", .Dim = c(1L, 1L)),
                         Add = structure("T", .Dim = c(1L, 1L))),
                    .Names = c("id", "Sample", "Add")),
  `2.1` = structure(list(id = structure(5, .Dim = c(1L, 1L)),
                         Sample = structure("Test2", .Dim = c(1L, 1L)),
                         Add = structure("A", .Dim = c(1L, 1L))),
                    .Names = c("id", "Sample", "Add")),
  `3.1` = structure(list(id = structure(7, .Dim = c(1L, 1L)),
                         Sample = structure("Test3", .Dim = c(1L, 1L)),
                         Add = structure("D", .Dim = c(1L, 1L))),
                    .Names = c("id", "Sample", "Add")),
  `4.1` = structure(list(id = structure(12, .Dim = c(1L, 1L)),
                         Sample = structure("Test4", .Dim = c(1L, 1L)),
                         Add = structure("Z", .Dim = c(1L, 1L))),
                    .Names = c("id", "Sample", "Add")),
  `5.1` = structure(list(id = structure(17, .Dim = c(1L, 1L)),
                         Sample = structure("Test12", .Dim = c(1L, 1L)),
                         Add = structure("E", .Dim = c(1L, 1L))),
                    .Names = c("id", "Sample", "Add"))),
  .Names = c("1.1", "2.1", "3.1", "4.1", "5.1"),
  row.names = c("id", "Sample", "Add"), class = "data.frame")

data
# 1.1   2.1   3.1   4.1    5.1
# id         1     5     7    12     17
# Sample Test1 Test2 Test3 Test4 Test12
# Add        T     A     D     Z      E

data2 <- as.data.frame(apply(data, 1, unlist))
data2
# id Sample Add
# 1.1  1  Test1   T
# 2.1  5  Test2   A
# 3.1  7  Test3   D
# 4.1 12  Test4   Z
# 5.1 17 Test12   E

data2 <- split(x = data2, f = data2$id)
data2
# $`1`
# id Sample Add
# 1.1  1  Test1   T
# 
# $`12`
# id Sample Add
# 4.1 12  Test4   Z
# 
# $`17`
# id Sample Add
# 5.1 17 Test12   E
# 
# $`5`
# id Sample Add
# 2.1  5  Test2   A
# 
# $`7`
# id Sample Add
# 3.1  7  Test3   D

data2 <- lapply(data2, function(x){
  as.data.frame(t(x))
})
data2
# $`1`
# 1.1
# id         1
# Sample Test1
# Add        T
# 
# $`12`
# 4.1
# id        12
# Sample Test4
# Add        Z
# 
# $`17`
# 5.1
# id         17
# Sample Test12
# Add         E
# 
# $`5`
# 2.1
# id         5
# Sample Test2
# Add        A
# 
# $`7`
# 3.1
# id         7
# Sample Test3
# Add        D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM