【问题标题】:Saving data held in a data frame produced using the "by" function保存保存在使用“by”函数生成的数据框中的数据
【发布时间】:2014-01-23 19:31:31
【问题描述】:

我使用“by”函数计算大量图形(有 4 个变量)的相关矩阵,并将结果保存在数据框中,如下所示:

results <- by(data, data$graphNumber, cor)

在哪里: data 是我的原始图形数据,data$graphNumber 是我用来窗格结果的变量,cor 是用来创建相关矩阵的函数

results 的样本:

d$graphNumber: 1
                x          y             z           T
x               1.0000000 0.9445139   0.9967193   0.9753503
y               0.9445139 1.0000000   0.9630660   0.9853882
z               0.9967193 0.9630660   1.0000000   0.9897238
T               0.9753503 0.9853882   0.9897238   1.0000000
------------------------------------------------------------------------------- 
d$graphNumber: 2
                x          y          z           T
x               1.0000000 0.9075414   0.9587088   0.9140054
y               0.9075414 1.0000000   0.9833022   0.9942477
z               0.9587088 0.9833022   1.0000000   0.9768249
T               0.9140054 0.9942477   0.9768249   1.0000000
------------------------------------------------------------------------------- 
...

我现在想将我的结果保存为 CSV。我试过使用:

write.table(results,"data.csv")

但这会返回错误:

Error in as.data.frame.default(results[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
  cannot coerce class '"by"' into a data.frame

我可以使用以下方法编写每个单独的矩阵:

write.table(results[1],"data.csv")

但是,我想将所有结果写入一个 CSV 文件,并通过某种方式识别每个矩阵对应的图形。


结果结构,str(results)

List of 1013
 $ 1 : num [1:4, 1:4] 1 0.945 0.997 0.975 0.945 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "x" "y" "z" "T"
  .. ..$ : chr [1:4] "x" "y" "z" "T"
 $ 2 : num [1:4, 1:4] 1 0.908 0.959 0.914 0.908 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "x" "y" "z" "T"
  .. ..$ : chr [1:4] "x" "y" "z" "T"

【问题讨论】:

    标签: r csv export-to-csv


    【解决方案1】:
    # generate sample data
    n <- 1000; graphNum <- 4
    data <- data.frame(x=runif(n, 1, 100), 
                       y=runif(n, 1, 100), 
                       graphNumber=gl(graphNum,n/graphNum))
    (results <- by(data[,1:2], data$graphNumber, cor))
    
    # to data frame
    (df <- do.call(rbind, lapply(results, as.data.frame)))
    #               x           y
    # 1.x  1.00000000 -0.13468673
    # 1.y -0.13468673  1.00000000
    # 2.x  1.00000000 -0.04512667
    # 2.y -0.04512667  1.00000000
    # 3.x  1.00000000  0.03609621
    # 3.y  0.03609621  1.00000000
    # 4.x  1.00000000 -0.04193474
    # 4.y -0.04193474  1.00000000
    

    稍后,您可以将 rownames 中的 graphNum 和 Var 分开

    strsplit(row.names(df), "\\.")
    

    【讨论】:

    • @Josh PS:也许你更喜欢save(results, file="test.RData")load("test.RData") 而不是类型转换。
    【解决方案2】:

    您可以使用do.callrbind 转换为data.frame

    resultsdf <- as.data.frame(do.call(rbind,results))
    

    但您必须在使用之前修复重复的行名:

    rownames(resultsdf) <- paste(rownames(resultsdf),rep(names(results),sapply(results,nrow)), sep=".")
    

    以 mtcars 数据为例:

    results <- by(mtcars[c("mpg","disp","hp")],mtcars$cyl,cor)
    
    resultsdf
                  mpg       disp         hp
    mpg.4   1.0000000 -0.8052361 -0.5235034
    disp.4 -0.8052361  1.0000000  0.4346051
    hp.4   -0.5235034  0.4346051  1.0000000
    mpg.6   1.0000000  0.1030827 -0.1270678
    disp.6  0.1030827  1.0000000 -0.5136284
    hp.6   -0.1270678 -0.5136284  1.0000000
    mpg.8   1.0000000 -0.5197670 -0.2836357
    disp.8 -0.5197670  1.0000000  0.1182556
    hp.8   -0.2836357  0.1182556  1.0000000
    

    【讨论】:

    • +1 这可行,但结果仍然是矩阵,而不是数据框。
    • 是的,你可以用as.data.frame 包裹它,但是会出现重复行名的错误,因此需要更改。
    • @James 这行得通,但您也无法分辨每个矩阵对应的组(或图)。我怎么能包含这些信息
    • @agstudy @Josh 我已经对其进行了编辑以使其正常工作,这在rownames 中提供了分组信息,但同样的方法也可以用于添加为额外的列
    • do.call(rbind.data.frame, ...) 应该直接得到data.frame
    【解决方案3】:

    获得data.frame 的一个选项是使用ddply

    n = 100
    library(plyr)
    dfx <- data.frame(
      graphNumber = c(rep('A', 8), rep('B', 15), rep('C', 6)),
      x = runif(n = 29, min = 18, max = 54),
      y = runif(n = 29, min = 18, max = 54)
    )
    ddply(dfx, .(graphNumber), function(x){
      cor(x[,-1])
    })
    
     graphNumber           x           y
    1           A  1.00000000  0.54914531
    2           A  0.54914531  1.00000000
    3           B  1.00000000 -0.02346146
    4           B -0.02346146  1.00000000
    5           C  1.00000000 -0.86352644
    6           C -0.86352644  1.00000000
    

    【讨论】:

      【解决方案4】:

      您可以melt列表中的每个数据框,然后转换为一个数据框。

      library(reshape2)
      library(plyr)
      
      results <- by(mtcars[ , 1:4], list(am = mtcars[, "am"]), cor)
      results
      # am: 0
      #             mpg        cyl       disp         hp
      # mpg   1.0000000 -0.7959989 -0.7926335 -0.8315065
      # cyl  -0.7959989  1.0000000  0.8294544  0.8454881
      # disp -0.7926335  0.8294544  1.0000000  0.8343294
      # hp   -0.8315065  0.8454881  0.8343294  1.0000000
      # ------------------------------------------------------------------------------------------------------ 
      #   am: 1
      #             mpg        cyl       disp         hp
      # mpg   1.0000000 -0.8259983 -0.8348954 -0.8006683
      # cyl  -0.8259983  1.0000000  0.9408836  0.9004347
      # disp -0.8348954  0.9408836  1.0000000  0.9240353
      # hp   -0.8006683  0.9004347  0.9240353  1.0000000
      
      results2 <- llply(results, melt)
      results2
      results3 <- ldply(results2)
      results3
      
      #    .id Var1 Var2      value
      # 1    0  mpg  mpg  1.0000000
      # 2    0  cyl  mpg -0.7959989
      # 3    0 disp  mpg -0.7926335
      # 4    0   hp  mpg -0.8315065
      # 5    0  mpg  cyl -0.7959989
      # 6    0  cyl  cyl  1.0000000
      # ...
      # 18   1  cyl  mpg -0.8259983
      # 19   1 disp  mpg -0.8348954
      # 20   1   hp  mpg -0.8006683
      # 21   1  mpg  cyl -0.8259983
      # 22   1  cyl  cyl  1.0000000
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-22
        • 1970-01-01
        相关资源
        最近更新 更多