根据另一个表中的值添加变量

时间:2017-09-08 14:09:35

标签: r

我有两张桌子。 第一个列出了所有人。

IND
1
2
3
4
5

第二张桌子的行是由每个人(每个人进行一次或多次移动)所做的移动(从一个地方到另一个地方)。第一列是IND号;另外两个是原产地(PLACE_A)(A,B或C)和目的地(PLACE_B)(A,B或C)。

IND PLACE_A PLACE_B
1   A   B
1   B   A
1   A   C
2   C   A
2   A   C
3   B   A
3   A   C
3   C   A
3   A   C
3   C   A
4   C   A
4   A   C
4   C   A
4   A   C
5   B   C
5   C   A

我希望在第一个表格中有一个新专栏,它会告诉我一个人曾经在一个特定的地方(让我们说B)。我想不出来。

IND LIVED_B
1   TRUE
2   FALSE
3   TRUE
4   FALSE
5   TRUE

3 个答案:

答案 0 :(得分:1)

使用data.table ...

library(data.table)
setDT(DF2)

indDT   = data.table(IND = 1:5)
placeDT = data.table(PLACE = LETTERS[1:3])
DT      = DF2[, .(PLACE = c(PLACE_A, PLACE_B[.N])), by=IND][, T := rowid(IND)][]

然后看看每个人是否都在每个地方......

DT[, table(
  IND   = factor(IND, levels = indDT$IND), 
  PLACE = factor(PLACE, levels = placeDT$PLACE)
) > 0L ]

   PLACE
IND    A     B    C
  1 TRUE  TRUE TRUE
  2 TRUE FALSE TRUE
  3 TRUE  TRUE TRUE
  4 TRUE FALSE TRUE
  5 TRUE  TRUE TRUE

factor次来电确保显示所有级别,即使数据集访问中没有人访问过。

答案 1 :(得分:1)

首先,我将数据放入data.frames:

IND = c(1, 2, 3, 4, 5)
tab1 = as.data.frame(list('IND' = IND, 
                          'LIVED_B' = rep(FALSE, length(IND))))
tab2 = as.data.frame(list('IND'=c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5),
                          'PLACE_A'=c("A", "B", "A", "C", "A", "B", "A", "C", "A", "C", "C", "A", "C", "A", "B", "C"),
                          'PLACE_B'=c("B", "A", "C", "A", "C", "A", "C", "A", "C", "A", "A", "C", "A", "C", "C", "A")))

如果这些PLACE_APLACE_B A 的位置无关,我会考虑重新命名列AB > B C

溶液

tab1$LIVED_B[tab2$IND[tab2$PLACE_A=='B']] = TRUE

结果:

  IND LIVED_B
1   1    TRUE
2   2   FALSE
3   3    TRUE
4   4   FALSE
5   5    TRUE

另一种解决方案

我们现在可能想要考虑位置C(之前没有声明列LIVED_C):

tab1$LIVED_C[tab2$IND[tab2$PLACE_A=='C']] = TRUE
tab1$LIVED_C[is.na(tab1$LIVED_C)] = FALSE

结果:

  IND LIVED_B LIVED_C
1   1    TRUE   FALSE
2   2   FALSE    TRUE
3   3    TRUE    TRUE
4   4   FALSE    TRUE
5   5    TRUE    TRUE

考虑列PLACE_A和PLACE_B

如果您还想考虑个人目前居住的地方(请考虑PLACE_A和PLACE_B列):

tab1$LIVED_or_STILL_LIVES_A[tab2$IND[as.logical((tab2$PLACE_A=='A') + (tab2$PLACE_B=='A'))]] = TRUE
tab1$LIVED_or_STILL_LIVES_A[is.na(tab1$LIVED_or_STILL_LIVES_A)] = FALSE

结果:

  IND LIVED_B LIVED_C LIVED_or_STILL_LIVES_A
1   1    TRUE   FALSE                   TRUE
2   2   FALSE    TRUE                   TRUE
3   3    TRUE    TRUE                   TRUE
4   4   FALSE    TRUE                   TRUE
5   5    TRUE    TRUE                   TRUE

答案 2 :(得分:0)

我相信弗兰克的答案是好的,也许另一个选择是使用嵌套选择,但这只适用于一列,正如你的问题所说。

SELECT 1 IND INTO #T1
INSERT INTO #T1 VALUES 
(2), (3), (4), (5)

SELECT 1 IND, 'A' PLACE_A, 'B' PLACE_B INTO #T2
INSERT INTO #T2 VALUES 
(1, 'B', 'A'), (1, 'A', 'C'), (2, 'C', 'A'), (2, 'B', 'A'), (2, 'A', 'C'), (3, 'B', 'A'), (3, 'C', 'A'), (3, 'A', 'C')

SELECT A.IND, A.LIVED_A FROM 
(SELECT A.IND, CASE WHEN PLACE_A = 'A' THEN 'TRUE' ELSE 'FALSE' END LIVED_A
FROM #T1 A INNER JOIN #T2 B ON A.IND = B.IND) A
WHERE A.LIVED_A = 'TRUE' GROUP BY A.IND, A.LIVED_A

问候!