当间隙小于n时,有效地完成数字

时间:2018-05-11 11:18:55

标签: r vectorization

我有以下数字向量:

n

如果它们之间的差距小于n=4,我想在v1中的每两个成员之间填写缺失的数字,让我们说v2 = c(1, 5, 10, 11, 12, 13, 20, 21, 22) 。所以在这种情况下我的结果将是:

USE TRIAL
GO

CREATE TABLE DETAILS
(
ID INT,
NAME VARCHAR(50),
ADDRESS VARCHAR(50)
)

INSERT INTO DETAILS
VALUES (100, 'POPE-JOHN-PAUL','VATICAN CIT|ROME|ITALY')
,(240, 'SIR-PAUL-McARTNEY','NEWYORK CITY|NEWYORK|USA')
,(460,'BARRACK-HUSSEIN-OBAMA','WHITE HOUSE|WASHINGTON|USA')
,(700, 'PRESIDENT-VLADAMIR-PUTIN','RED SQUARE|MOSCOW|RUSSIA')
,(950, 'NARENDRA-DAMODARDAS-MODI','10 JANPATH|NEW DELHI|INDIA')

select [ID]
,[NAME]
,[ADDRESS]
,REPLACE(LEFT(NAME, CHARINDEX('-', NAME)),'-',' ') as First_Name
,CASE 
WHEN CHARINDEX('-',REVERSE(NAME))+ CHARINDEX('-',NAME) < LEN(NAME)
THEN  SUBSTRING(NAME, CHARINDEX('-', (NAME)) + 1, LEN(NAME) - CHARINDEX('-' 
, REVERSE(NAME)) - CHARINDEX('-', NAME))
  ELSE 'NULL
  END AS Middle_Name
,REPLACE(REVERSE( SUBSTRING( REVERSE(NAME), 1, CHARINDEX('- 
',REVERSE(NAME)))), '-','') AS Last_Name 
,REPLACE(LEFT(ADDRESS, CHARINDEX('|', ADDRESS)),'|',' ') AS Locality
,CASE 
    WHEN CHARINDEX('|',REVERSE(ADDRESS))+ CHARINDEX('|',ADDRESS) < 
  LEN(ADDRESS) 
 THEN SUBSTRING(ADDRESS, CHARINDEX('|', (ADDRESS))+1, LEN(ADDRESS)- 
CHARINDEX('|', REVERSE(ADDRESS))-CHARINDEX('|',ADDRESS))
  ELSE 'Null' 
END AS STATE
,REPLACE(REVERSE(SUBSTRING(REVERSE(ADDRESS),1 
,CHARINDEX('|',REVERSE(ADDRESS)))),'|','') AS Country
 FROM DETAILS
  SELECT CHARINDEX('-', REVERSE(NAME)) AS LAST,CHARINDEX('-',NAME)AS FIRST, 
 LEN(NAME) AS LENGTH
 FROM DETAILS

有没有办法有效地为很长的载体做到这一点?

2 个答案:

答案 0 :(得分:0)

如果没有这么多索引,也许某人有更好的解决方案,但你可以这样做,例如:

v1 = c(1, 5, 10, 11, 13, 20, 22)

d <- diff(v1)
idx <- which(d < 4 & d > 1)

unlist(sapply(seq_along(v1), function(x) {
  if (x %in% idx) {
    seq(v1[x], v1[x+1] - 1)
  } else {
    v1[x]
  }
}))

[1]  1  5 10 11 12 13 20 21 22

答案 1 :(得分:0)

这是一个有效的hacky解决方案(可能不是解决此类问题的最佳方法)。 将difference < 4替换为:并将此字符串解析为text:

# Input
foo <- c(1, 5, 10, 11, 13, 20, 22)

bar <- ifelse(c(diff(foo) < 4), ":", ",")
# [1] "," "," ":" ":" "," ":"
foobar <- paste(foo[1], paste(bar, foo[-1], collapse = ""), collapse = ",")
# [1] "1 , 5, 10: 11: 13, 20: 22"
eval(parse(text = paste0("c(", foobar, ")")))
# [1] 1  5 10 11 12 13 20 21 22