簡體   English   中英

如何在R中的reshape包中循環dcast函數

[英]How to loop dcast function in reshape package in R

作為一個相對較新的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個輸出? 它瘋狂地循環着。

我希望這不像我看來那么復雜。 任何幫助(以及一些詳細的解釋)或有用的方向將是大量和真誠的贊賞。 謝謝

你寫了:

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")

希望這能說明你做錯了什么。

“all.data”是一個數據幀列表。 要遍歷列表,您可以使用lapply和匿名函數調用(只是為了清楚)並在其上應用dcast

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

或者,而不是做個人dcast ,該列表可以rbind到數據幀與每個列表元素,然后分組變量要么做dcastspreadlibrary(tidyr)

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"))

我會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”將反映這些名字,從長遠來看這可能非常方便。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM