【问题标题】:data formatting: reformat AND rearrange multiple dataframes in r into single file数据格式化:重新格式化并将 r 中的多个数据帧重新排列到单个文件中
【发布时间】:2017-11-12 01:48:15
【问题描述】:

我有许多 .csv 文件,它们是来自其他来源的自动格式化数据。这些数据的顺序对于我(任何人的!)分析来说都是可怕的。理想情况下,我想将所有这些单独的 .csv 文件合并到一个数据框中,其中每一行代表原始数据框的内容,并且该行中的第一列具有原始数据框的名称。

我能够使用列表自动导入每个原始数据框

#import from working directory
temp = list.files(pattern="*.csv")
list2env(
  lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))), 
         read.csv), envir = .GlobalEnv)

#make a new list of dataframes that I should be able to use with "lapply"
files<-eapply(.GlobalEnv,is.data.frame)

我想按以下方式重新格式化列表中的每个数据框:

#reproducible example original format
df1<-data.frame(matrix(NA, nrow=3, ncol=3))
colnames(df1)<-c("area", "mean", "sd")
rownames(df1)<-c("A", "B", "C")
df1[1:3,1]<-30
df1[,2]<-sample(80:100, 3, replace=TRUE)
df1[,3]<-sample(1:5, 3, replace=TRUE)
df1

   area mean sd
A   30   81  1
B   30   96  3
C   30   97  4

df2<-data.frame(matrix(NA, nrow=3, ncol=3))
colnames(df2)<-c("area", "mean", "sd")
rownames(df2)<-c("A", "B", "C")
df2[1:3,1]<-35
df2[,2]<-sample(80:100, 3, replace=TRUE)
df2[,3]<-sample(1:5, 3, replace=TRUE)
df2

   area mean sd
A   35   82  2
B   35   99  1
C   35  100  3

#desired final format:
  filename area.1 mean.1a sd.1a mean.1b sd.1b mean.1c sd.1c
1    file1     30      81     1      96     3      97     4
2    file2     35      82     2      99     1     100     3

我一直在尝试编写一个丑陋的循环,基本上就是这样做的:

#desired final format
df1.2<-data.frame(matrix(NA, nrow=2, ncol=8))
colnames(df1.2)<-c("filename", "area.1", "mean.1a", "sd.1a", "mean.1b", "sd.1b", "mean.1c", "sd.1c")
df1.2[1,1]<-"file1"
df1.2[1,2]<-df1[1,1] 
df1.2[1,3]<-df1[1,2] 
df1.2[1,4]<-df1[1,3]
df1.2[1,5]<-df1[2,2] 
df1.2[1,6]<-df1[2,3]
df1.2[1,7]<-df1[3,2]
df1.2[1,8]<-df1[3,3]

但我无法弄清楚如何从列表中操作数据框中的单个元素

我知道必须有一种有效的方法来做到这一点,但我以前从未真正使用过列表,我不知道如何让它按照我想要的方式运行。我发现的所有示例似乎都在使用 lapply 来做一些更基本的事情,比如平均整行或更改整个属性,而不是复制列表中数据框中的单个元素。

我对列表不是很熟悉,我认为这引起了我的心痛。我很想帮助使用 lapply 和/或 for 循环(或一些我不知道的绝妙函数),这样我就可以编写一个脚本来遍历列表中的所有数据帧,或者同时包含文件名作为第一列,或者稍后使用“rbind”添加它。

【问题讨论】:

  • subset 操纵不是你要找的吗?
  • 我不确定subset 在这里如何应用。我已经接受了下面的答案,感谢您的参与!

标签: r list csv dataframe lapply


【解决方案1】:

我是否正确理解您的输入数据是数据框列表?

如果是这样,这里有一团胶带可以让你到达那里。

biglist <- list()
areas <- seq(30,45,by=5)
for(i in 1:4) {
  biglist[[i]]<-data.frame(matrix(NA, nrow=3, ncol=3))
  colnames(biglist[[i]])<-c("area", "mean", "sd")
  rownames(biglist[[i]])<-c("A", "B", "C")
  biglist[[i]][1:3,1]<-areas[i]
  biglist[[i]][,2]<-sample(80:100, 3, replace=TRUE)
  biglist[[i]][,3]<-sample(1:5, 3, replace=TRUE)
}
biglist
## [[1]]
##   area mean sd
## A   30  100  3
## B   30   86  1
## C   30   85  1
## 
## [[2]]
##   area mean sd
## A   35   83  4
## B   35   87  2
## C   35   88  4
## 
## [[3]]
##   area mean sd
## A   40   92  4
## B   40   80  3
## C   40   90  5
## 
## [[4]]
##   area mean sd
## A   45   97  2
## B   45   92  3
## C   45   92  5

现在有趣的部分...

df1.2<-data.frame(matrix(NA, nrow=length(biglist), ncol=8))
colnames(df1.2)<-c("filename", "area.1", "mean.1a", "sd.1a", "mean.1b", "sd.1b", "mean.1c", "sd.1c")

for(i in 1:length(biglist)) {
  df1.2[i,2:8] <- c(biglist[[i]][1,], biglist[[i]][2,2:3], biglist[[i]][3,2:3])
}
df1.2$filename <- paste0("file",1:length(biglist))

df1.2
##   filename area.1 mean.1a sd.1a mean.1b sd.1b mean.1c sd.1c
## 1    file1     30     100     3      86     1      85     1
## 2    file2     35      83     4      87     2      88     4
## 3    file3     40      92     4      80     3      90     5
## 4    file4     45      97     2      92     3      92     5   

不是最优雅的,但这能满足你的需要吗?

【讨论】:

  • 谢谢,马特,这“一团胶带”正是我所需要的!原来我的部分问题是我生成列表的方式实际上并没有包含数据帧....我自己想出这个。非常非常感谢!
【解决方案2】:

如果每个数据框的行数相同,您可以用unlist将它们展平,然后将它们绑定到一个公共数据框中。例如:

df1 <- unlist(df1)
df2 <- unlist(df2)

df <- data.frame()
df <- rbind(df, c("file1", df1), stringsAsFactors = F)
df <- rbind(df, c("file2", df2), stringsAsFactors = F)

colnames(df) <- c("filname", names(df1))

df <- df[,-c(3:4)]

输出:

  filname area1 mean1 mean2 mean3 sd1 sd2 sd3
1   file1    30    94    96    99   2   2   3
2   file2    35    92    95    90   2   3   5

【讨论】:

  • 谢谢@ssp3nc3r。我曾考虑按照您的建议将它们展平为一个数据框,然后从那里重新排列,但我有超过 200 个要连接,我担心如果我这样做会丢失某些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多