【问题标题】:How to loop dcast function in reshape package in R如何在 R 中的 reshape 包中循环 dcast 函数
【发布时间】:2015-07-09 16:00:03
【问题描述】:

作为一个相对较新的 R 用户,我在使用任何循环函数时都遇到了麻烦。我看过很多教程,但其中的示例通常非常基础,因此易于执行。但是,我需要创建稍微复杂一些的循环,并且在弄清楚如何这样做时遇到了很多麻烦。在这里和其他论坛上有一些相关的循环问题,但没有一个完全符合我的需要,尽管我已经尝试为我当前的问题调整其他答案,但我一直遇到错误。

我有 2000 个 .csv 文件,其中的数据以长格式数据制成表格(简化示例):

solution1    
> sol1     sol2     Istat
> s1       s2       0.435
> s1       s3       0.456
> s1       s4       0.845
> s1       s5       0.234

它基本上是对我拥有的 2000 个单独解决方案的两两比较的总结,解决方案之间的相似性总结在一个“Istat”值中。

我正在尝试将这 2000 个 .csv 文件中的每一个 dcast 到宽格式表中(使用 R 中的 reshape 包),因此它们看起来像(以下示例如下):

     s1     s2     s3     s4     s5
s1   NA     0.435  0.456  0.845  0.234

我只知道如何使用单个 .csv 文件执行此操作:

stat.cast <- dcast(solution1, sol2 ~ sol1, value.var="Istat")

但我似乎无法将其用于for 循环函数,甚至无法使用lapply,这似乎也是一个可能的解决方案。

我能用for 函数得到的最接近的函数:

 # Get files from directory
loopout = "/Users/jc219806/Documents/Chapter 1/ANALYSES/R work/Istat/last_LoopOut/"
# List of file names inside folder
solutions <- list.files(loopout)
# Read all 2000 files inside
all.data <- lapply(solutions, read.csv, header=TRUE)
# Loop for performing reshape cast function to each listed dataframe
for (i in 1:length(all.data))
  {
  all.cast <- dcast(all.data, sol2 ~ sol1, value.var="Istat")
  }

但它一直给我一个错误,即它无法从输入中识别“Istat”值 - 即使它在我拥有的数据框列表中(上面代码中的“解决方案”对象)。

还有lapply 函数:

lapply(solutions, dcast(all.data, sol2 ~ sol1, value.var="Istat"))

我得到相同类型的错误:

Error: value.var (Istat) not found in input

我不明白为什么,因为它列在数据帧列表中,作为 2000 个数据帧中的每一个中的变量之一。似乎我没有让它正确地循环遍历我的 2000 个 .csv 文件,但我不知道如何解决这个问题。我还想知道是否也可以编写代码,以便根据列名将所有 2000 个输出绑定在一起循环?循环太疯狂了。

我希望这不是一个像我认为的那样复杂的问题。任何帮助(以及一些详细的解释)或有用的方向都将受到极大和真诚的感谢。谢谢

【问题讨论】:

  • 我猜应该是sol1~sol2 才能获得您所显示的预期结果。

标签: r loops reshape lapply


【解决方案1】:

"all.data" 是数据帧的列表。要遍历列表,您可以使用 lapply 和匿名函数调用(为了清楚起见)并在其上应用 dcast

library(reshape2)
lapply(all.data, function(x) dcast(x, sol1 ~ sol2, value.var="Istat"))

或者代替单独的dcast,列表可以是rbind 到每个列表元素具有分组变量的数据帧,然后从library(tidyr) 执行dcastspread

library(dplyr)
library(tidyr)
unnest(all.data, group) %>% 
                  spread(sol2, Istat)

或使用data.table

library(data.table)
dcast(rbindlist(Map(cbind, all.data, group=seq_along(all.data))),
                 group + sol1 ~sol2, value.var='Istat')

数据

all.data <- structure(list(solution1 = structure(list(sol1 = c("s1", 
"s1", 
"s1", "s1"), sol2 = c("s2", "s3", "s4", "s5"), Istat = c(0.435, 
0.456, 0.845, 0.234)), .Names = c("sol1", "sol2", "Istat"), 
class =     "data.frame", row.names = c(NA, 
-4L)), solution2 = structure(list(sol1 = c("s1", "s1", "s1", 
"s1"), sol2 = c("s2", "s3", "s4", "s5"), Istat = c(0.42, 0.536, 
0.945, 0.324)), .Names = c("sol1", "sol2", "Istat"), 
class =    "data.frame", row.names = c(NA, 
-4L))), .Names = c("solution1", "solution2"))

【讨论】:

  • 我看到我们的想法与您的更新相同。 +1 :-)
  • @AnandaMahto 你发布解决方案时我正在更新。
【解决方案2】:

你写道:

for (i in 1:length(all.data))
  {
  all.cast <- dcast(all.data, sol2 ~ sol1, value.var="Istat")
  }

你应该写的:

all.cast <- list()
for (i in 1:length(all.data)) {
  all.cast[[i]] <- dcast(all.data[[i]], sol2 ~ sol1, value.var = "Istat")
}

但更“R-esque”的解决方案是:

all.cast <- lapply(all.data, dcast, sol2 ~ sol1, value.var = "Istat")

希望这能说明你做错了什么。

【讨论】:

    【解决方案3】:

    我会melt你的“all.data”列表,然后dcast它是一个宽泛的形式。比如:

    ## Sample data
    set1 <- set2 <- data.frame(sol1 = c("s1", "s1", "s1", "s1"), 
                       sol2 = c("s2", "s3", "s4", "s5"), 
                       Istat = c(0.435, 0.456, 0.845, 0.234))
    set2$Istat <- set2$Istat + 1 ## Just to see some different data
    
    all.data <- mget(ls(pattern = "set\\d+")) ## use your actual object
    
    ## The reshaping
    library(reshape2)
    dcast(melt(all.data, id.vars = c("sol1", "sol2")), 
          L1 + sol1 ~ sol2, value.var = "value")
    #     L1 sol1    s2    s3    s4    s5
    # 1 set1   s1 0.435 0.456 0.845 0.234
    # 2 set2   s1 1.435 1.456 1.845 1.234
    

    如果您的“all.data”对象有名称,“L1”将反映这些名称,从长远来看这会非常方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-10
      • 2021-02-16
      • 2019-07-26
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多