根据 R 中另一个数据框中的比较值更改一个数据框中的值
Alter values in one data frame based on comparison values in another in R
我正在尝试将 POSIXct 列中的 date/times 减去一小时,该列早于或等于该特定 ID 的不同比较数据框中规定的时间。
例如:
#create sample data
Time<-as.POSIXct(c("2015-10-02 08:00:00","2015-11-02 11:00:00","2015-10-11 10:00:00","2015-11-11 09:00:00","2015-10-24 08:00:00","2015-10-27 08:00:00"), format = "%Y-%m-%d %H:%M:%S")
ID<-c(01,01,02,02,03,03)
data<-data.frame(Time,ID)
产生这个:
Time ID
1 2015-10-02 08:00:00 1
2 2015-11-02 11:00:00 1
3 2015-10-11 10:00:00 2
4 2015-11-11 09:00:00 2
5 2015-10-24 08:00:00 3
6 2015-10-27 08:00:00 3
然后我有另一个数据框,其中包含每个 ID 的关键日期和时间以供比较。数据中的时间应该与 ComparisonData 中的 Comparison 进行比较,以获取与之关联的特定 ID。如果数据中的时间值早于或等于比较值,则应从数据中的值中减去一小时:
#create sample comparison data
Comparison<-as.POSIXct(c("2015-10-29 08:00:00","2015-11-02 08:00:00","2015-10-26 08:30:00"), format = "%Y-%m-%d %H:%M:%S")
ID<-c(01,02,03)
ComparisonData<-data.frame(Comparison,ID)
这应该是这样的:
Comparison ID
1 2015-10-29 08:00:00 1
2 2015-11-02 08:00:00 2
3 2015-10-26 08:30:00 3
综上所述,代码应该检查某个ID的所有时间,看是否有任何时间早于或等于ComparisonData中指定的值,如果是,则减去一小时。这应该将此数据框作为输出:
Time ID
1 2015-10-02 07:00:00 1
2 2015-11-02 11:00:00 1
3 2015-10-11 09:00:00 2
4 2015-11-11 09:00:00 2
5 2015-10-24 07:00:00 3
6 2015-10-27 08:00:00 3
我看过类似的解决方案,例如 this,但我无法理解如何使用具有特定 ID 的正确时间来检查时间。
我认为 ddply 似乎是一个很有前途的选择,但我不确定如何使用它来解决这个特定问题。
我相信会有比这更好的解决方案,但是,我认为这是可行的。
for(i in 1:nrow(data)) {
if(data$Time[i] < ComparisonData[data$ID[i], 1]){
data$Time[i] <- data$Time[i] - 3600
}
}
# Time ID
#1 2015-10-02 07:00:00 1
#2 2015-11-02 11:00:00 1
#3 2015-10-11 09:00:00 2
#4 2015-11-11 09:00:00 2
#5 2015-10-24 07:00:00 3
#6 2015-10-27 08:00:00 3
这将遍历 data
中的每一行。
ComparisonData[data$ID[i], 1]
获取 ComparisonData
中对应 ID
的 time
列。如果这大于 data
中的 Time
列,则将时间减少 1 小时。
这是一个使用 data.table
的快速有效的解决方案。首先我们通过 ID
连接两个数据集,然后只修改小于或等于 Comparison
的 Time
library(data.table) # v1.9.6+
setDT(data)[ComparisonData, end := i.Comparison, on = "ID"]
data[Time <= end, Time := Time - 3600L][, end := NULL]
data
# Time ID
# 1: 2015-10-02 07:00:00 1
# 2: 2015-11-02 11:00:00 1
# 3: 2015-10-11 09:00:00 2
# 4: 2015-11-11 09:00:00 2
# 5: 2015-10-24 07:00:00 3
# 6: 2015-10-27 08:00:00 3
或者,我们可以在使用 ifelse
加入时一步完成此操作(虽然不确定效率如何)
setDT(data)[ComparisonData,
Time := ifelse(Time <= i.Comparison,
Time - 3600L, Time),
on = "ID"]
data
# Time ID
# 1: 2015-10-02 07:00:00 1
# 2: 2015-11-02 11:00:00 1
# 3: 2015-10-11 09:00:00 2
# 4: 2015-11-11 09:00:00 2
# 5: 2015-10-24 07:00:00 3
# 6: 2015-10-27 08:00:00 3
我正在尝试将 POSIXct 列中的 date/times 减去一小时,该列早于或等于该特定 ID 的不同比较数据框中规定的时间。
例如:
#create sample data
Time<-as.POSIXct(c("2015-10-02 08:00:00","2015-11-02 11:00:00","2015-10-11 10:00:00","2015-11-11 09:00:00","2015-10-24 08:00:00","2015-10-27 08:00:00"), format = "%Y-%m-%d %H:%M:%S")
ID<-c(01,01,02,02,03,03)
data<-data.frame(Time,ID)
产生这个:
Time ID
1 2015-10-02 08:00:00 1
2 2015-11-02 11:00:00 1
3 2015-10-11 10:00:00 2
4 2015-11-11 09:00:00 2
5 2015-10-24 08:00:00 3
6 2015-10-27 08:00:00 3
然后我有另一个数据框,其中包含每个 ID 的关键日期和时间以供比较。数据中的时间应该与 ComparisonData 中的 Comparison 进行比较,以获取与之关联的特定 ID。如果数据中的时间值早于或等于比较值,则应从数据中的值中减去一小时:
#create sample comparison data
Comparison<-as.POSIXct(c("2015-10-29 08:00:00","2015-11-02 08:00:00","2015-10-26 08:30:00"), format = "%Y-%m-%d %H:%M:%S")
ID<-c(01,02,03)
ComparisonData<-data.frame(Comparison,ID)
这应该是这样的:
Comparison ID
1 2015-10-29 08:00:00 1
2 2015-11-02 08:00:00 2
3 2015-10-26 08:30:00 3
综上所述,代码应该检查某个ID的所有时间,看是否有任何时间早于或等于ComparisonData中指定的值,如果是,则减去一小时。这应该将此数据框作为输出:
Time ID
1 2015-10-02 07:00:00 1
2 2015-11-02 11:00:00 1
3 2015-10-11 09:00:00 2
4 2015-11-11 09:00:00 2
5 2015-10-24 07:00:00 3
6 2015-10-27 08:00:00 3
我看过类似的解决方案,例如 this,但我无法理解如何使用具有特定 ID 的正确时间来检查时间。
我认为 ddply 似乎是一个很有前途的选择,但我不确定如何使用它来解决这个特定问题。
我相信会有比这更好的解决方案,但是,我认为这是可行的。
for(i in 1:nrow(data)) {
if(data$Time[i] < ComparisonData[data$ID[i], 1]){
data$Time[i] <- data$Time[i] - 3600
}
}
# Time ID
#1 2015-10-02 07:00:00 1
#2 2015-11-02 11:00:00 1
#3 2015-10-11 09:00:00 2
#4 2015-11-11 09:00:00 2
#5 2015-10-24 07:00:00 3
#6 2015-10-27 08:00:00 3
这将遍历 data
中的每一行。
ComparisonData[data$ID[i], 1]
获取 ComparisonData
中对应 ID
的 time
列。如果这大于 data
中的 Time
列,则将时间减少 1 小时。
这是一个使用 data.table
的快速有效的解决方案。首先我们通过 ID
连接两个数据集,然后只修改小于或等于 Comparison
Time
library(data.table) # v1.9.6+
setDT(data)[ComparisonData, end := i.Comparison, on = "ID"]
data[Time <= end, Time := Time - 3600L][, end := NULL]
data
# Time ID
# 1: 2015-10-02 07:00:00 1
# 2: 2015-11-02 11:00:00 1
# 3: 2015-10-11 09:00:00 2
# 4: 2015-11-11 09:00:00 2
# 5: 2015-10-24 07:00:00 3
# 6: 2015-10-27 08:00:00 3
或者,我们可以在使用 ifelse
加入时一步完成此操作(虽然不确定效率如何)
setDT(data)[ComparisonData,
Time := ifelse(Time <= i.Comparison,
Time - 3600L, Time),
on = "ID"]
data
# Time ID
# 1: 2015-10-02 07:00:00 1
# 2: 2015-11-02 11:00:00 1
# 3: 2015-10-11 09:00:00 2
# 4: 2015-11-11 09:00:00 2
# 5: 2015-10-24 07:00:00 3
# 6: 2015-10-27 08:00:00 3