【问题标题】:Lists to Dataframes with NA or 0使用 NA 或 0 列出数据帧
【发布时间】:2013-04-01 15:21:19
【问题描述】:

我有一个包含 138 个表的列表(prop.table)。每个表中最多可以有 20 个变量(数字类别范围为 11-95 作为列名)。我需要将此列表转换为主数据框。前三个表如下所示:

[[1]]
x
        21         41         42         43         52         71         81         82 
0.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 

[[2]]
x
        21         41         42         43         52         71         90 
0.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 

[[3]]
x
         21          22          23          41          42 
0.043254082 0.008307075 0.016614151 0.930392438 0.001432254 

当分类变量不可用时,我需要将其转换为矩阵,使其看起来像这样,NAs 或 0:

x<-matrix (nrow=3, ncol=11 )
colnames(x) <-c('21', '22', '23', '41', '42', '43', '52', '71', '81', '82', '90' )

我曾尝试使用之前类似问题中的这一行,但表格不正确:

df <- data.frame(matrix(unlist(prop.table), nrow=138, byrow=T))

关于如何解决这个问题并获得我需要的表格有什么建议吗?

【问题讨论】:

    标签: r list matrix dataframe


    【解决方案1】:

    这是你想要的吗?

    x1 <- c(1, 5, 7)
    names(x1) <- 1:3
    x2 <- c(1, 2, 7)
    names(x2) <- c(1,3,5)
    l <- list(x1, x2)
    
    m <- matrix(nrow=length(l), ncol=5)
    colnames(m) <- 1:5
    for (i in 1:length(l)) {
      m[i, names(l[[i]])] <- l[[i]]
    }
    

    也许可以用apply 函数替换循环,但我不确定...基本上,我循环遍历列表并在矩阵的每一行中设置与向量名称匹配的列在列表中。

    很抱歉没有使用您的数据集,但您手头没有代码,我懒得打出来。

    【讨论】:

    • 感谢您的快速响应。这似乎不起作用。可能是因为我的 prop.table 对象是一个包含 138 个不同表的列表。我最初以为这是一个包含 138 个列表的列表,但事实证明它们是表格。
    【解决方案2】:

    我只是建议一种解决方案。您如何将所有列表连接在一起。所以你会有

    MyDataFrame
    variable1         1          1          1          1          1          1          1          1
    variable2        21         41         42         43         52         71         81         82 
    variable30.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 
    
    variable1         2          2          2          2          2          2          2 
    variable2        21         41         42         43         52         71         90 
    variable30.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 
    
    variable1          3           3           3           3           3
    variable2         21          22          23          41          42 
    variable30.043254082 0.008307075 0.016614151 0.930392438 0.001432254 
    

    一旦你只有一个数据框。您可以使用重塑功能。喜欢

    install.packages('reshape')
    library('reshape')
    cast(MyDataFrame, variable1~variable2)
    

    【讨论】:

      【解决方案3】:

      这不是最有效的,但使用plyrreshape2,并假设您的prop.tables 列表称为foo

      library(plyr)
      library(reshape2)
      
      
      allData <- dcast(ldply(lapply(seq_along(foo), function(x) data.frame(foo[[x]], id = x))), 
                      id ~ x, value.var = 'Freq')
      

      或者更直接

      ff <- c('21', '22', '23', '41', '42', '43', '52', '71', '81', '82', '90' )
      
      t(sapply(foo, function(x,y) {x[ff]} ))
      

      【讨论】:

      • 感谢您的快速响应。这似乎不起作用。可能是因为我的 prop.table 对象是一个包含 138 个不同表的列表。我最初以为这是一个包含 138 个列表的列表,但事实证明它们是表格。
      • @IDelToro -- 通过包含dput(head(prop.table.list)) 使您的问题可重现(其中prop.table.list 是您的道具表列表
      • prop.table.list&lt;-lapply(Landcover, function(x) prop.table(table(x))) dput(head(prop.table.list))
      • 你再次拯救了这一天 :) 干杯!
      【解决方案4】:

      plyr 包中的rbind.fill 将为您执行此操作:

      # make an example `prop.table`:
      tbl <- 1:10
      names(tbl) <- letters[1:10]
      tbl <- as.matrix(tbl)
      
      # make sure some of the columns are missing
      prop.table <- list(tbl[sample(10, size=8),], tbl[sample(10, size=7),], tbl[sample(10, size=9),])
      # [[1]]
      # d b g c h f e i 
      # 4 2 7 3 8 6 5 9 
      # [[2]]
      #  h  g  d  a  j  f  c 
      #  8  7  4  1 10  6  3 
      # [[3]]
      #  c  i  b  d  j  a  h  g  e 
      # 3  9  2  4 10  1  8  7  5 
      

      您可以使用plyr 中的rbind.fill 函数,它只是rbind,但它会用NA 填充缺失的列。它可以将数据帧列表一起放入rbind,因此我首先将prop.table 的每个元素转换为数据帧(需要t 以确保每个prop.table[[i]] 被视为一行,而不是一列)

      rbind.fill(lapply(prop.table, function (x) as.data.frame(t(x))))
      #   d  b g c h  f  e  i  a  j
      # 1 4  2 7 3 8  6  5  9 NA NA
      # 2 4 NA 7 3 8  6 NA NA  1 10
      # 3 4  2 7 3 8 NA  5  9  1 10
      

      (注意 - 您可以使用 x[, order(colnames(x))] 对输出数据框的列进行排序)

      【讨论】:

        【解决方案5】:

        这是使用lapplyrbinddo.call的简单方法

        ptl
        ## [[1]]
        ## x
        ##         21         41         42         43         52         71         81         82 
        ## 0.02007456 0.58158876 0.22483510 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 
        ## 
        ## [[2]]
        ## x
        ##         21         41         42         43         52         71         90 
        ## 0.01175122 0.36973345 0.34107194 0.03066781 0.08655775 0.01633706 0.14388077 
        ## 
        ## [[3]]
        ## x
        ##          21          22          23          41          42 
        ## 0.043254082 0.008307075 0.016614151 0.930392438 0.001432254 
        ## 
        ## [[4]]
        ## x
        ##         21         22         31         41         42         43         81 
        ## 0.10028653 0.03123209 0.00487106 0.66103152 0.03037249 0.01604585 0.15616046 
        ## 
        ## [[5]]
        ## x
        ##           21           41           42           43           81 
        ## 0.0662080825 0.8291774147 0.0005732302 0.0865577529 0.0174835196 
        ## 
        ## [[6]]
        ## x
        ##          21          22          31          41          42          43          81 
        ## 0.081948424 0.002292264 0.006303725 0.825501433 0.029226361 0.020630372 0.034097421 
        ## 
        
        
        # Get unique names of all columns in tables in the list
        resCol <- unique(unlist(lapply(ptl, names)))
        
        # Get dimensions of desired result
        nresCol <- length(resCol)
        nresRow <- length(ptl)
        
        # Create 'Template' data.frame row
        DF <- as.data.frame(matrix(rep(0, nresCol), nrow = 1, dimnames = list(1, resCol)))
        
        # for every table in list, create copy of DF, fill it appropriately, then rbind result together using do.call
        
        result <- do.call(rbind, lapply(ptl, function(x) {
            retDF <- DF
            retDF[, names(x)] <- x
            return(retDF)
        }))
        
        # rename rows(optional)
        rownames(result) <- 1:nrow(result)
        
        result
        ##           21        41           42         43         52         71         81         82        90          22         23          31
        ## 1 0.02007456 0.5815888 0.2248351018 0.09349011 0.05248064 0.01204474 0.00544881 0.01003728 0.0000000 0.000000000 0.00000000 0.000000000
        ## 2 0.01175122 0.3697334 0.3410719404 0.03066781 0.08655775 0.01633706 0.00000000 0.00000000 0.1438808 0.000000000 0.00000000 0.000000000
        ## 3 0.04325408 0.9303924 0.0014322544 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.0000000 0.008307075 0.01661415 0.000000000
        ## 4 0.10028653 0.6610315 0.0303724928 0.01604585 0.00000000 0.00000000 0.15616046 0.00000000 0.0000000 0.031232092 0.00000000 0.004871060
        ## 5 0.06620808 0.8291774 0.0005732302 0.08655775 0.00000000 0.00000000 0.01748352 0.00000000 0.0000000 0.000000000 0.00000000 0.000000000
        ## 6 0.08194842 0.8255014 0.0292263610 0.02063037 0.00000000 0.00000000 0.03409742 0.00000000 0.0000000 0.002292264 0.00000000 0.006303725
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          相关资源
          最近更新 更多