为满足条件 R 的每一行创建一个新列

make a new column for each row that meets a criteria R

我有两个数据集。第一个有某人的位置和他们到不同目的地的英里距离。第二个数据集包含所有目的地的列表。我想让 R 创建一个列,提取 1000 英里以外的每个目的地的名称。

这是第一个数据集的示例:

library(tidyverse)
start_location <- tibble(location = c("Anhui China", "Amersfoort Utrecht Netherlands", "Akita Akita Japan"),
lon = c(117.92, 5.38, 140.1),
lat = c(30.60, 52.16, 39.71),
dist_beijing = c(658, 5686, 1250),
dist_shanghai = c(241, 5510, 1200),
dist_tokyo = c(1300, 5775, 280),
dist_prague = c(5173, 417, 5415), 
dist_pomezia = c(5555, 474, 5927),
dist_antwerp = c(5498, 77, 5612))

这是第二个数据集

library(tidyverse)
destinations <- tibble(destinations = c("beijing china", "shanghai china", "tokyo japan", "prague czech republic", "pomezia italy", "antwerp belgium"),
lon = c(116.4, 121.47, 139.65, 14.43, 12.50, 4.40),
lat = c(39.90, 31.23, 35.67, 50.07, 41.67, 51.22))

这是我希望数据集的样子:

library(tidyverse)
solution <- tibble(location = c("Anhui China", "Amersfoort Utrecht Netherlands", "Akita Akita Japan"),
lon = c(117.92, 5.38, 140.1),
lat = c(30.60, 52.16, 39.71),
nearest1 = c("shanghai china", "antwerp belgium", "tokyo japan"),
nearest2 = c("beijing china", "prague czech republic", NA),
nearest3 = c(NA, "pomezia italy", NA))

我知道如何让它找到最短距离,但我正在努力让它为每个列生成一个列名。另外,虽然这个有三个最近的,但我不一定想将它限制为只有 3 个。我只是希望它为 1000 英里以下的每个目的地制作列。

我想我应该使用 case_when 和 pmap,但我不知道如何添加 if 语句并允许它生成多列。

如果它不能很容易地制作列,我也可以让它制作一个列,按顺序列出 1000 英里以下的所有目的地(例如,如果 "beijing china, shanghai china"),因为那样我可以至少用 tidyr 把它分开。

此外,如果可能的话,我想要一个整洁的解决方案。

谢谢!!

这是一个 tidyverse 解决方案:

result<-start_location %>% gather("destination","distance",-(1:3)) %>%
  filter(distance<=1000) %>% 
  group_by(location) %>% 
  arrange(distance) %>% 
  mutate(id=paste0("nearest",row_number())) %>% 
  select(-5) 
result$destination<-gsub("dist_","",result$destination)
result$destination<-sapply(result$destination, function(x) grep(x,destinations$destinations,value=TRUE))
result<-result %>% spread(id, destination)

# A tibble: 3 x 6
# Groups:   location [3]
  location                     lon   lat nearest1       nearest2          nearest3   
  <chr>                      <dbl> <dbl> <chr>          <chr>             <chr>      
1 Akita Akita Japan         140.    39.7 tokyo japan    NA                NA         
2 Amersfoort Utrecht Nethe~   5.38  52.2 antwerp belgi~ prague czech rep~ pomezia it~
3 Anhui China               118.    30.6 shanghai china beijing china     NA 

关键在于按距离排列目的地(已按起始位置分组),然后根据它们的顺序分配一个 id 标签——然后您可以 spread 目的地根据这些 id 标签分成列。

我在 spread 之前添加了几个步骤,将目标列的名称替换为 destinations 数据帧中目标的实际名称——如果你有,这可能会引入一些错误一个目的地城市也是一个国家的名称(例如,墨西哥城)并且该国家/地区也出现在另一个目的地中,所以请记住这一点。