首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何有效地使用哪一()来比较r中的一列和一行?

如何有效地使用哪一()来比较r中的一列和一行?
EN

Stack Overflow用户
提问于 2016-05-16 23:32:51
回答 3查看 67关注 0票数 2

数据

我有多个车辆数据集,每个都有一个唯一的ID,Vehicle.ID2。以下是仅供一辆车使用的数据:

代码语言:javascript
运行
复制
df <- structure(list(Vehicle.ID2 = c("4-2", "4-2", "4-2", "4-2", "4-2", 
"4-2", "4-2", "4-2", "4-2", "4-2", "4-2", "4-2", "4-2", "4-2", 
"4-2", "4-2", "4-2", "4-2", "4-2", "4-2"), Time = c(3, 3.2, 3.4, 
3.6, 3.8, 4, 4.2, 4.4, 4.6, 4.8, 5, 5.2, 5.4, 5.6, 5.8, 6, 6.2, 
6.4, 6.6, 6.8), yposition = c(3.451, 7.357, 11.264, 15.171, 19.077, 
22.984, 26.89, 30.797, 34.704, 38.61, 42.517, 46.423, 50.33, 
54.236, 58.143, 62.05, 65.956, 69.863, 73.769, 77.676), LeadVehyposition2 = c(55.043, 
NA, 64.098, 68.626, 73.153, 77.681, 82.209, 86.736, 91.264, 95.791, 
100.319, 104.847, 109.374, 113.902, 118.429, 122.957, 127.485, 
132.012, 136.54, 141.067)), .Names = c("Vehicle.ID2", "Time", 
"yposition", "LeadVehyposition2"), class = c("tbl_df", "data.frame"
), row.names = c(NA, -20L))

我想做什么

我希望将LeadVehyposition2ypositiondf中进行比较,并输出第一个Time,其中yposition大于或等于LeadVehyposition2。使用1 vehicle,我可以通过对LeadVehyposition2中的第一个值使用以下代码来实现这一点

代码语言:javascript
运行
复制
df$Time[head(which(df$yposition>=55.043),1)]
> 5.8

在这里,LeadVehyposition2中的第一个值是55.043,我将它与yposition中的所有值进行了比较。我想对LeadVehyposition2中的所有值做同样的处理。以下是不适用于整个数据集(多个车辆ID)的代码:

代码语言:javascript
运行
复制
library(dplyr)
mydata %>%
group_by(Vehicle.ID2) %>% 
mutate(Time.PET = Time[head(which(yposition>=LeadVehyposition2),1)]%>%
ungroup()

问题:

问题是,使用第二段代码只能按行比较ypositionLeadVehyposition2的值。但是,我们的目标是保持LeadVehyposition2不变,并将其与整个yposition列进行比较。我该如何解决这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-16 23:45:34

下面是一种在base中实现该功能的可能方法;

代码语言:javascript
运行
复制
df$Time[sapply(df$LeadVehyposition2, function(p) min(which(df$yposition >= p)))]
 [1] 5.8  NA 6.2 6.4 6.6  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

或者:

代码语言:javascript
运行
复制
with(df, Time[sapply(LeadVehyposition2, function(p) min(which(yposition >= p)))])
 [1] 5.8  NA 6.2 6.4 6.6  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

为处理按车辆分类的问题:

代码语言:javascript
运行
复制
df <- df[order(df$Vehicle.ID2, df$Time), ]
do.call(c, sapply(split(df, df$Vehicle.ID2), function(df) 
        with(df, Time[sapply(LeadVehyposition2, function(p) min(which(yposition >= p)))])))
票数 3
EN

Stack Overflow用户

发布于 2016-05-17 01:17:34

一个data.table方法可以是将df加入到自己,然后取最小TimeypositionLeadVehyposition2之间有一个正的区别。

代码语言:javascript
运行
复制
library(data.table)
setDT(df)

res <- df[ df[, .(Vehicle.ID2, Time, yposition)], on = c("Vehicle.ID2"), allow.cartesian=T][i.yposition - LeadVehyposition2 > 0, .(min(i.Time)), by = .(Vehicle.ID2, Time, LeadVehyposition2)]
res
#     Vehicle.ID2 Time LeadVehyposition2  V1
# 1:         4-2  3.0            55.043 5.8
# 2:         4-2  3.4            64.098 6.2
# 3:         4-2  3.6            68.626 6.4
# 4:         4-2  3.8            73.153 6.6

将此返回到df将向原始数据添加额外的列。

代码语言:javascript
运行
复制
res[df, on = c("Vehicle.ID2","Time","LeadVehyposition2")]

#      Vehicle.ID2 Time LeadVehyposition2  V1 yposition
#  1:         4-2  3.0            55.043 5.8     3.451
#  2:         4-2  3.2                NA  NA     7.357
#  3:         4-2  3.4            64.098 6.2    11.264
#  4:         4-2  3.6            68.626 6.4    15.171
#  5:         4-2  3.8            73.153 6.6    19.077
#  6:         4-2  4.0            77.681  NA    22.984
# ...
# 17:         4-2  6.2           127.485  NA    65.956
# 18:         4-2  6.4           132.012  NA    69.863
# 19:         4-2  6.6           136.540  NA    73.769
# 20:         4-2  6.8           141.067  NA    77.676
票数 3
EN

Stack Overflow用户

发布于 2016-05-17 02:25:49

为此,可以使用滚动联接:

代码语言:javascript
运行
复制
library(data.table)
setDT(df)

# create an index to be used for matching
df[, idx := 1:.N, by = Vehicle.ID2]

# find the matching index using rolling joins
df[, idx.m := .SD[.SD, on = c('Vehicle.ID2', yposition = 'LeadVehyposition2'), roll = T,
                 idx + 1]][1:5]
#   Vehicle.ID2 Time yposition LeadVehyposition2 idx idx.m
#1:         4-2  3.0     3.451            55.043   1    15
#2:         4-2  3.2     7.357                NA   2    NA
#3:         4-2  3.4    11.264            64.098   3    17
#4:         4-2  3.6    15.171            68.626   4    18
#5:         4-2  3.8    19.077            73.153   5    19

# get the time for each match
df[, Time.PET := Time[idx.m], by = Vehicle.ID2][1:5]
#   Vehicle.ID2 Time yposition LeadVehyposition2 idx idx.m Time.PET
#1:         4-2  3.0     3.451            55.043   1    15      5.8
#2:         4-2  3.2     7.357                NA   2    NA       NA
#3:         4-2  3.4    11.264            64.098   3    17      6.2
#4:         4-2  3.6    15.171            68.626   4    18      6.4
#5:         4-2  3.8    19.077            73.153   5    19      6.6

如果ypositionLeadVehyposition2可以严格相等,我建议将非常小(正)的抖动添加到yposition中,以使上面的操作正确。

另一个选项是,使用最新开发版本 of data.table添加非赤道联接,可以是:

代码语言:javascript
运行
复制
library(data.table)
setDT(df)

df[df, on = .(Vehicle.ID2, yposition >= LeadVehyposition2), Time[1], by = .EACHI][1:5]
#   Vehicle.ID2 yposition  V1
#1:         4-2    55.043 5.8
#2:         4-2        NA  NA
#3:         4-2    64.098 6.2
#4:         4-2    68.626 6.4
#5:         4-2    73.153 6.6

它读取-在列中加入df,其中Vehicle.ID2是相同的,yposition大于或等于LeadVehyposition2,然后为每个"i“(也就是[.data.table的第一个参数)取第一个Time

当然,您可以将其指定为一列:

代码语言:javascript
运行
复制
df[, Time.PET := .SD[.SD, on = .(Vehicle.ID2, yposition >= LeadVehyposition2),
                    Time[1], by = .EACHI]$V1]

注意:两种答案都假定yposition已经按递增顺序排序。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37264808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档