R 从多个两列数据帧中读入、转置和合并数据帧,第一行共用
我有数千个逗号分隔的.txt文件,有两列,其中一列的列名为“波长”,所有文件的波长值都相同(“x”值),另一列的列名和响应值为文件名(各种观察到的“y”值) 如果我通过readr读取单个文件,格式如下所示:R 从多个两列数据帧中读入、转置和合并数据帧,第一行共用,r,dataframe,merge,dplyr,tidyr,R,Dataframe,Merge,Dplyr,Tidyr,我有数千个逗号分隔的.txt文件,有两列,其中一列的列名为“波长”,所有文件的波长值都相同(“x”值),另一列的列名和响应值为文件名(各种观察到的“y”值) 如果我通过readr读取单个文件,格式如下所示: # A tibble: 2,151 x 2 Wavelength a1lm_00000.asd.ref.sco.txt ### [filename] <dbl> <dbl> 1 350
# A tibble: 2,151 x 2
Wavelength a1lm_00000.asd.ref.sco.txt ### [filename]
<dbl> <dbl>
1 350 0.0542
2 351 0.0661
3 352 0.0686
4 353 0.0608
5 354 0.0545
6 355 0.0589
7 356 0.0644
8 357 0.0587
9 358 0.0556
10 359 0.0519
...etc.
换句话说,我需要第一列作为文件标识符,后面的每一列都是光谱响应,相关的光谱波长作为列名
因此,我需要从目录中读取所有这些文件,并且:
a、 )创建第三列,即文件名,使所有第二列的名称类似于“response”,将bind_行应用于所有文件,然后在tidyr包中使用“spread”
b、 )读取每个文件后,立即对其进行转置,使第一行成为所有列名,第二行列名按文件名插入行标识符的第一列中,并对这些结果行进行行绑定
备选案文b。似乎更可取。这两个选项中的任何一个似乎都需要使用lapply,可能需要使用bind_rows或bind_cols。但我不知道怎样才能最好地做到这一点。有很多数据,我使用的一些方法导致我的机器内存不足,所以内存效率越高,效果越好 我建议将所有
数据.frame
存储在列表中。然后,合并data.frame
s,将数据从宽转换为长,然后使用不同的键返回到宽,就成了一个简单的问题
library(tidyverse)
reduce(lst, full_join) %>%
gather(file, value, -Wavelength) %>%
spread(Wavelength, value)
# file 350 351 352 353 354 355 356
#1 a1lm_00000.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
#2 a1lm_00001.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
# 357 358 359
#1 0.0587 0.0556 0.0519
#2 0.0587 0.0556 0.0519
还有两条评论:
要将data.frame
s存储在列表中,我会按照映射(文件名,~read\u csv2(.x))
(或在基本Rlappy中(文件名,函数(x)read.csv(x))
)的思路做一些事情。根据需要调整文件名
和读取csv2
/读取.csv
参数
更一般地说,我可能会建议不要采用这种格式。将数据保存在一个长(且整齐)的data.frame
列表中似乎要容易得多李>
为了完整性,可以在base R中使用Reduce
+merge
连接数据,并使用stack
+重塑
从宽到长再宽进行转换
df <- Reduce(merge, lst)
reshape(
cbind(stack(df, select = -Wavelength), Wavelength = df$Wavelength),
idvar = "ind", timevar = "Wavelength", direction = "wide")
# ind values.350 values.351 values.352 values.353
#1 a1lm_00000.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608
#11 a1lm_00001.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608
# values.354 values.355 values.356 values.357 values.358 values.359
#1 0.0545 0.0589 0.0644 0.0587 0.0556 0.0519
#11 0.0545 0.0589 0.0644 0.0587 0.0556 0.0519
df我建议将所有数据.frame
s存储在列表中。然后,合并data.frame
s,将数据从宽转换为长,然后使用不同的键返回到宽,就成了一个简单的问题
library(tidyverse)
reduce(lst, full_join) %>%
gather(file, value, -Wavelength) %>%
spread(Wavelength, value)
# file 350 351 352 353 354 355 356
#1 a1lm_00000.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
#2 a1lm_00001.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608 0.0545 0.0589 0.0644
# 357 358 359
#1 0.0587 0.0556 0.0519
#2 0.0587 0.0556 0.0519
还有两条评论:
要将data.frame
s存储在列表中,我会按照映射(文件名,~read\u csv2(.x))
(或在基本Rlappy中(文件名,函数(x)read.csv(x))
)的思路做一些事情。根据需要调整文件名
和读取csv2
/读取.csv
参数
更一般地说,我可能会建议不要采用这种格式。将数据保存在一个长(且整齐)的data.frame
列表中似乎要容易得多李>
为了完整性,可以在base R中使用Reduce
+merge
连接数据,并使用stack
+重塑
从宽到长再宽进行转换
df <- Reduce(merge, lst)
reshape(
cbind(stack(df, select = -Wavelength), Wavelength = df$Wavelength),
idvar = "ind", timevar = "Wavelength", direction = "wide")
# ind values.350 values.351 values.352 values.353
#1 a1lm_00000.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608
#11 a1lm_00001.asd.ref.sco.txt 0.0542 0.0661 0.0686 0.0608
# values.354 values.355 values.356 values.357 values.358 values.359
#1 0.0545 0.0589 0.0644 0.0587 0.0556 0.0519
#11 0.0545 0.0589 0.0644 0.0587 0.0556 0.0519
df这起作用了。它仍然比我想要的慢。我试图模拟asdreader包的get_Spectrum函数的功能。我不能在我的数据上使用get_spectra,因为我必须稍微更改拼接校正的格式(通过专有软件),get_spectra不会读取拼接校正ASCII文件输出,只读取原始原始文件。不知何故,get_spectra读取数据的速度要比您的方法快得多,但我不知道如何在包中“查看引擎盖下”以了解代码是如何工作的。@我不知道get_spectra
的作用。但是有很多方法可以优化从CSV文件中读取和处理数据。在阅读方面,最快的方法可能是使用data.table
sfread
,尤其是在处理大型CSV文件时(参见示例)。我还添加了一个base R解决方案,您可能希望使用tidyverse
方法对其进行基准测试。它仍然比我想要的慢。我试图模拟asdreader包的get_Spectrum函数的功能。我不能在我的数据上使用get_spectra,因为我必须稍微更改拼接校正的格式(通过专有软件),get_spectra不会读取拼接校正ASCII文件输出,只读取原始原始文件。不知何故,get_spectra读取数据的速度要比您的方法快得多,但我不知道如何在包中“查看引擎盖下”以了解代码是如何工作的。@我不知道get_spectra
的作用。但是有很多方法可以优化从CSV文件中读取和处理数据。在阅读方面,最快的方法可能是使用data.table
sfread
,尤其是在处理大型CSV文件时(参见示例)。我还添加了一个base R解决方案,您可能希望使用tidyverse
方法对其进行基准测试。