我有一个大数据框,包含几个探针执行的不同测量。
测量的时间并不完全相同。由于我想在给定时间比较两个测量值并在动画中绘制它们,我需要将数据“同步”。
这是我得到的数据帧的一个例子(在现实生活中,我有更多的列,我直接从文本文件中读取):
time1.in.s <- seq(0.010, 100, length.out = 100)
time2.in.s <- seq(0.022, 100, length.out = 100)
data1 <- seq(-10, 100, length.out = 100)
data2 <- seq(-25, 80, length.out = 100)
my.df <- data.frame(time1.in.s, data1, time2.in.s, data2)
给出了:
time1.in.s data1 time2.in.s data2
1 0.01 -10.000000 0.022000 -25.0000000
2 1.02 -8.888889 1.031879 -23.9393939
3 2.03 -7.777778 2.041758 -22.8787879
4 3.04 -6.666667 3.051636 -21.8181818
5 4.05 -5.555556 4.061515 -20.7575758
6 5.06 -4.444444 5.071394 -19.6969697
我想要做的是在一个“时间”列中合并两个timeX.in.s列。在数据不可用的情况下,我会使用na.approx(my.df$data1, x = my.df$time)
提供此代码以便您可以重现该问题,但在现实生活中,time1.in.s,time2.in.s,data1和data2不能单独提供。我实际做的是my.df <- read.table(my.file, header = TRUE)
,我得到了相同的结果。因此,我无法直接构建单独的数据框,我需要手动分割一个大数据框:
df.list <- list()
for (i in seq(1, ncol(my.df), 2)) {
df.list[[ceiling(i/2)]] <- data.frame(time = my.df[, i], data = my.df[, i+1])
}
然后逐个合并数据框:
merged.df <- data.frame(time = as.numeric(NA), data = as.numeric(NA))
for (i in 1:length(df.list)) {
merged.df <- merge(merged.df, df.list[[i]], by = "time", all = TRUE)
}
最后填补空白:
merged.df$data.y <- na.approx(merged.df$data.y, x = merged.df$time, na.rm = FALSE)
这肯定有效(除了列的名称是一个很大的混乱)。但它很麻烦,对我来说看起来不太对劲。有更简单的方法吗?
以下是使用上述命令获得的结果:
> head(merged.df)
time data.x data.y data
1 0.010000 NA -10.000000 NA
2 0.022000 NA -9.986799 -25.00000
3 1.020000 NA -8.888889 NA
4 1.031879 NA -8.875821 -23.93939
5 2.030000 NA -7.777778 NA
6 2.041758 NA -7.764843 -22.87879
列data.x来自最初的empty merged.df。它可以被倾倒。 列data.y是my.df $ data1列。 在上面的数据框中,我没有对列数据使用na.approx命令(对应于my.df $ data2列)
关于OmaymaS提议的解决方案的补充说明:
为了使这项工作在一般情况下(即任意数量的列),我所做的是以下内容。首先,我定义了一个6列数据框:
time1.in.s <- seq(0.010, 100, length.out = 100)
time2.in.s <- seq(0.022, 100, length.out = 100)
time3.in.s <- seq(0.017, 99.8, length.out = 100)
data1 <- seq(-10, 100, length.out = 100)
data2 <- seq(-25, 80, length.out = 100)
data3 <- seq(-15, 70, length.out = 100)
my.df <- data.frame(time1.in.s, data1, time2.in.s, data2, time3.in.s, data3)
这导致:
head(my.df)
time1.in.s data1 time2.in.s data2 time3.in.s data3
1 0.01 -10.000000 0.022000 -25.00000 0.017000 -15.00000
2 1.02 -8.888889 1.031879 -23.93939 1.024909 -14.14141
3 2.03 -7.777778 2.041758 -22.87879 2.032818 -13.28283
4 3.04 -6.666667 3.051636 -21.81818 3.040727 -12.42424
5 4.05 -5.555556 4.061515 -20.75758 4.048636 -11.56566
6 5.06 -4.444444 5.071394 -19.69697 5.056545 -10.70707
我将包含时间的所有列的名称更改为相同的名称(这样我就不必告诉merge
函数合并哪个列by
):
colnames(my.df)[seq(1, ncol(my.df), 2)] <- "Time"
然后我循环一个略微修改的Reduce函数:
df.merged <- my.df[, 1:2]
for (i in seq(3, ncol(my.df), 2)) {
df.merged <- Reduce(function(x,y) merge(x,y,
all = TRUE),
list(df.merged,
my.df[, i:(i+1)])
)
}
这给出了:
> head(df.merged)
Time data1 data2 data3
1 0.010000 -10.000000 NA NA
2 0.017000 NA NA -15.00000
3 0.022000 NA -25.00000 NA
4 1.020000 -8.888889 NA NA
5 1.024909 NA NA -14.14141
6 1.031879 NA -23.93939 NA
最后,我应用了na.approx
函数:
df.interp <- df.merged
df.interp[, 2:ncol(df.interp)] <- na.approx(df.interp[, 2:ncol(df.interp)],
x = df.interp$Time,
na.rm = FALSE)
以下是最终结果:
> head(df.interp)
Time data1 data2 data3
1 0.010000 -10.000000 NA NA
2 0.017000 -9.992299 NA -15.00000
3 0.022000 -9.986799 -25.00000 -14.99574
4 1.020000 -8.888889 -23.95187 -14.14560
5 1.024909 -8.883488 -23.94671 -14.14141
6 1.031879 -8.875821 -23.93939 -14.13548
我仍然在某些数据列的开头有NAs,但我可以使用na.omit
函数删除它们。
答案 0 :(得分:2)
尝试合并,它应该可以帮助您实现所需:
首先:创建两个包含数据和相应时间的数据框:
df1 <- data.frame(time1.in.s, data1)
df2 <- data.frame(time2.in.s, data2)
第二步:合并两个数据帧,使用by.x和by.y指定要使用的列,并包括所有值:
df.merged <- merge(df1,df2,
by.x = "time1.in.s",
by.y = "time2.in.s",
all.x = TRUE,
all.y = TRUE)
注意:根据Sotos建议澄清:
all.x = TRUE,
all.y = TRUE
类似于
all = TRUE
因此,如果要从另一个中不存在的数据帧中排除值,可以将all.x或all.y设置为FALSE。
现在您将有时间在列中,您可以根据需要重命名列。
> head(df.merged)
time1.in.s data1 data2
1 0.010000 -10.000000 NA
2 0.022000 NA -25.00000
3 1.020000 -8.888889 NA
4 1.031879 NA -23.93939
5 2.030000 -7.777778 NA
6 2.041758 NA -22.87879
编辑:如果您想在多个 timen.in.s- datan 的多列上应用此功能,可以尝试按如下方式进行缩减,可以在列表中添加多个选项,并且所有选择都将根据时间列合并,假设它始终是select中的第一个。
df.merged <- Reduce(function(x,y) merge(x,y,
by.x = names(x)[1],
by.y = names(y)[1],
all = TRUE),
list(select(my.df,time1.in.s, data1),
select(my.df,time2.in.s, data2))
)
> head(df.merged)
time1.in.s data1 data2
1 0.010000 -10.000000 NA
2 0.022000 NA -25.00000
3 1.020000 -8.888889 NA
4 1.031879 NA -23.93939
5 2.030000 -7.777778 NA
6 2.041758 NA -22.87879
附加说明:
如果您想使用列'indecies,可以使用:
df.merged <- Reduce(function(x,y) merge(x,y,
by.x = names(x)[1],
by.y = names(y)[1],
all = TRUE),
list(select(my.df,1,2),
select(my.df,3,4))
)
同样如果列的名称一致,并且您想自动构建列表,则可以创建一个取整数并返回要选择的列名称的函数: p>
getDF <- function(x)
{
c1 <- paste0("time",x,".in.s")
c2 <- paste0("data",x)
return(c(c1,c2))
}
例如:
> getDF(1)
[1] "time1.in.s" "data1"
然后你可以在reduce:
中使用它df.merged <- Reduce(function(x,y) merge(x,y,
by.x = names(x)[1],
by.y = names(y)[1],
all = TRUE),
list(my.df[,getDF(1)],
my.df[,getDF(2)])
)
答案 1 :(得分:0)
一些代码。
我假设您希望将每CREATE TABLE mytable(
ExtractTypeNum INTEGER NOT NULL --PRIMARY KEY
,FileOrderNum VARCHAR(11)
,PrevFileOrderNum VARCHAR(11)
,NextFileOrderNum VARCHAR(11)
,rownum1 INTEGER
,Statusflag1 VARCHAR(9)
);
INSERT INTO mytable(ExtractTypeNum,FileOrderNum,PrevFileOrderNum,NextFileOrderNum,rownum1,Statusflag1)
VALUES (1,'2016-09-191',NULL,'2016-09-192',1,'IsInitial');
INSERT INTO mytable(ExtractTypeNum,FileOrderNum,PrevFileOrderNum,NextFileOrderNum,rownum1,Statusflag1)
VALUES (2,'2016-09-192','2016-09-191','2016-09-201',2,NULL);
INSERT INTO mytable(ExtractTypeNum,FileOrderNum,PrevFileOrderNum,NextFileOrderNum,rownum1,Statusflag1)
VALUES (3,'2016-09-201','2016-09-192','2016-09-211',3,NULL);
select 'Update Table Xyz Set Abc='+Convert(varchar(25),rownum1)+' ' as X,*
from myTable
列分开
data.frame