r - 按 NA 行拆分多个数据帧中的数据帧
问题描述
- 问题解释:
我有一个数据框(参见代码中的 sim.Dat.file6),它以交替的方式具有数值和 NA 值。我想提取单个数据框中的数值并省略 NA 值。
- 我的数据:我模拟了这个数据集,以便在 R 中提供一个清晰且可重复的示例。
#simulated data set:
set.seed(101)
x <- rep(factor(c(sample(c("a","b",3.5,"d","e","f","a1","b1",2.4,"d=",0,"f3"), 6), rnorm(c(1:6), 0.5, 0.1))),3)
y <- rep(factor(c(sample(c("a","b",3.5,"d","e","f","a1","b1",2.4,"d=",0,"f3"), 6), rnorm(c(1:6), 200, 5))),3)
z1 <- rep(factor(c(sample(c("a","b",3.5,"d","e","f","a1","b1",2.4,"d=",0,"f3"), 6), rep(0,6))),3)
z2 <- rep(factor(c(sample(c("a","b",3.5,"d","e","f","a1","b1",2.4,"d=",0,"f3"), 6), rep(0,6))),3)
sim.Dat.file <- data.frame(x, y, z1, z2)
sim.Dat.file2 <- sim.Dat.file[,-c(3:4)]
sim.Dat.file3 <- data.frame(Wavelength = as.numeric(paste(sim.Dat.file2$y)), Absorption = as.numeric(paste(sim.Dat.file2$x)))
#omit false Wavelength values
allNA <-function(x) {
if(x>180 | is.na(x)==TRUE){
return(x)
}else{
x<-NA
}
}
sim.Dat.file4 <-as.data.frame(sapply(sim.Dat.file3$Wavelength, allNA))
#omit false Absorption values
allNA <-function(x) {
if((x<1 & x>0)| is.na(x)==TRUE){
return(x)
}else{
x<-NA
}
}
sim.Dat.file5 <-as.data.frame(sapply(sim.Dat.file3$Absorption, allNA))
sim.Dat.file6 <-data.frame(sim.Dat.file4, sim.Dat.file5)
colnames(sim.Dat.file6) <-c("Absorption", "Wavelength")
#strategy1
splitFUN <- function(x) {
split(x, is.na(x==TRUE))
}
sim.Dat.file7 <- lapply(sim.Dat.file6, splitFUN)
#different spectra are merged together
我现在卡住了,因为到目前为止,strsplit
在split
我的情况下不起作用。如果我使用split(df5, if.na(df5)==TRUE
(如代码所示),我将 NA 值和数值分成两组(但我不能将它们分成单独的光谱并单独绘制每个光谱)。我将 NA 值更改为字符并尝试了 a strsplit
,但这也不能正常工作。
#output of lapply-split extractet with dput
list(Absorption = list(`FALSE` = c(199.033310175013, 195.751226298331,
200.292327489247, 195.91164822062, 189.748460921802, 199.181221670293,
199.033310175013, 195.751226298331, 200.292327489247, 195.91164822062,
189.748460921802, 199.181221670293, 199.033310175013, 195.751226298331,
200.292327489247, 195.91164822062, 189.748460921802, 199.181221670293
), `TRUE` = c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_)),
Wavelength = list(`FALSE` = c(0.53107692173136, 0.61739662875627,
0.561878985562597, 0.488726568524579, 0.591702828951271,
0.477674063537274, 0.53107692173136, 0.61739662875627, 0.561878985562597,
0.488726568524579, 0.591702828951271, 0.477674063537274,
0.53107692173136, 0.61739662875627, 0.561878985562597, 0.488726568524579,
0.591702828951271, 0.477674063537274), `TRUE` = c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_)))
- 数据转换的目的:
我想自动从数据集中提取数值。提取的值应在数据框中一个接一个地添加,或者每组数字提取值应保存在单独的数据框中。在这种情况下,最佳输出将是
output.data.frame <- data.frame(spectra1= sim.Dat.file6[7:12,], spectra2= sim.Dat.file6[19:24,], spectra3= sim.Dat.file6[31:36,])
output.data.frame
spectra1.Absorption spectra1.Wavelength spectra2.Absorption spectra2.Wavelength spectra3.Absorption
7 199.0333 0.5310769 199.0333 0.5310769 199.0333
8 195.7512 0.6173966 195.7512 0.6173966 195.7512
9 200.2923 0.5618790 200.2923 0.5618790 200.2923
10 195.9116 0.4887266 195.9116 0.4887266 195.9116
11 189.7485 0.5917028 189.7485 0.5917028 189.7485
12 199.1812 0.4776741 199.1812 0.4776741 199.1812
spectra3.Wavelength
7 0.5310769
8 0.6173966
9 0.5618790
10 0.4887266
11 0.5917028
12 0.4776741
解决方案
我认为以下内容以一种非常简单的方式完成了您想要的操作。
res_wave <- sim.Dat.file3$Wavelength[!is.na(sim.Dat.file3$Wavelength)]
res_abso <- sim.Dat.file3$Absorption[!is.na(sim.Dat.file3$Absorption)]
result <- data.frame(res_wave, res_abso)
> head(result)
res_wave res_abso
1 0.0000 2.4000000
2 199.0333 0.5310769
3 195.7512 0.6173966
4 200.2923 0.5618790
5 195.9116 0.4887266
6 189.7485 0.5917028
NA 值使用 idiom 过滤掉x[!is.na(x)]
。顺便说一句,我不清楚你想用你的功能实现什么
testfunction <-function(x) {
if((x<1 & x>0)| is.na(x)){
print("condition is true on first element")
return(x)
}else{
print("condition is false on first element")
x<-NA
}
}
testdata1 <- c(0.5,1,NA)
testdata2 <- c(999,1,NA)
testfunction(testdata1)
# > testfunction(testdata1)
# [1] "condition is true on first element"
# [1] 0.5 1.0 NA
# Warning message:
# In if ((x < 1 & x > 0) | is.na(x)) { :
# the condition has length > 1 and only the first element will be used
# testfunction(testdata2)
# [1] "condition is false on first element"
# Warning message:
# In if ((x < 1 & x > 0) | is.na(x)) { :
# the condition has length > 1 and only the first element will be used
如果其第一个元素满足您的条件,此函数将返回作为参数传递的相同向量(其所有原始值) 。
如果第一个元素不满足您的条件,它将不返回任何内容,只会执行x<-NA
将更改to中的所有值。x
NA
除了在这种情况下它不会更改对象,因为您是x
在函数环境内部而不是在全局环境中更改。正如您在下面看到的,data2
保持不变,因为它只是在函数内更改。
> testdata2
[1] 999 1 NA
为了在.Globalenv()
函数中修改 from 中的对象,您可以使用<<-
而不是在<-
这里,但我认为问题在于您不知道 R 的矢量化方面。
如果 data1 是vector
,data1 > 0
将返回一个,长度与 相同的值的向量。但该语句只考虑了这些布尔值中的第一个。TRUE
FALSE
data1
if
尝试查看我的解决方案并了解它是如何工作的。如您所见,R 中的矢量化允许您绕过对许多循环和函数的需求。
推荐阅读
- python - python中的确定性分布噪声
- r - ggplot 仅在 y 轴上显示正值(分面图)
- jquery - jQuery多维数组和范围
- json - 当键为空字符串时,如何在sqlite中检索json对象中的值?
- python - 如何配置多个 django 应用程序以使用同一个数据库?
- javascript - 从blob保存文件:http使用javascript没有重定向
- css - 检查时如何更改背景颜色
- java - 在本机代码中调试 java 进程崩溃
- python-3.x - samples.cols == var_count && samples.type() == 5 in function 'cv::ml::SVMImpl::predict' svm.predict 方法错误
- java - 将 TYPE 注释传递给方法而不是标记接口