Иметь возвращаемое значение nomatch как-использует функцию match в R

у меня есть гораздо больший существующий фрейм данных. Для этого меньшего примера я хотел бы заменить некоторые переменные (replace state (df1)) на newstate (df2) в соответствии со столбцом "first."Моя проблема заключается в том, что значения возвращаются как NA, поскольку только некоторые из имен сопоставляются в новом фрейме данных (df2).

существующий фрейм данных:

state = c("CA","WA","OR","AZ")
first = c("Jim","Mick","Paul","Ron")
df1 <- data.frame(first, state)

      first state
    1   Jim    CA
    2  Mick    WA
    3  Paul    OR
    4   Ron    AZ

новый фрейм данных в соответствии с существующим фреймом данных

state = c("CA","WA")
newstate = c("TX", "LA")
first =c("Jim","Mick")
df2 <- data.frame(first, state, newstate)

  first state newstate
1   Jim    CA       TX
2  Mick    WA       LA

пытался использовать матч, но возвращает NA для "состояния", где соответствующая" первая " переменная из df2 не найдена в исходном фрейме данных.

df1$state <- df2$newstate[match(df1$first, df2$first)]

  first state
1   Jim    TX
2  Mick    LA
3  Paul  <NA>
4   Ron  <NA>

есть ли способ игнорировать nomatch или nomatch возвращает существующую переменную как есть? Это был бы пример желаемого результата: состояния Джима/Мика обновляются, в то время как состояние пола и Рона не меняется.

      first state
    1   Jim    TX
    2  Mick    LA
    3  Paul    OR
    4   Ron    AZ

3 ответов


Это то, что вы хотите; кстати, если вы действительно не хотите работать с факторами, используйте stringsAsFactors = FALSE в своих данных.кадр вызова. Обратите внимание на использование nomatch = 0 в вызове матча.

> state = c("CA","WA","OR","AZ")
> first = c("Jim","Mick","Paul","Ron")
> df1 <- data.frame(first, state, stringsAsFactors = FALSE)
> state = c("CA","WA")
> newstate = c("TX", "LA")
> first =c("Jim","Mick")
> df2 <- data.frame(first, state, newstate, stringsAsFactors = FALSE)
> df1
  first state
1   Jim    CA
2  Mick    WA
3  Paul    OR
4   Ron    AZ
> df2
  first state newstate
1   Jim    CA       TX
2  Mick    WA       LA
> 
> # create an index for the matches
> indx <- match(df1$first, df2$first, nomatch = 0)
> df1$state[indx != 0] <- df2$newstate[indx]
> df1
  first state
1   Jim    TX
2  Mick    LA
3  Paul    OR
4   Ron    AZ

Я думаю, что вы получите лучшее поведение с векторами характер, чем с причинами.

> df1 <- data.frame(first, state,stringsAsFactors=FALSE)
> state = c("CA","WA")
> newstate = c("TX", "LA")
> first =c("Jim","Mick")
> df2 <- data.frame(first, state, newstate, stringsAsFactors=FALSE)
> df1[ match(df2$first, df1$first ), "state"] <- df2$newstate
> df1
  first state
1   Jim    TX
2  Mick    LA
3  Paul    OR
4   Ron    AZ

library(data.table)
DT1 <- as.data.table(df1)
DT2 <- as.data.table(df2)


setkey(DT1, first, state)
setkey(DT2, first, state)

DT1[DT2]
#    first state newstate
# 1:   Jim    CA       TX
# 2:  Mick    WA       LA

отметим, что [.data.table также nomatch аргумент, то есть:

DT2[DT1, nomatch=0]
#    first state newstate
# 1:   Jim    CA       TX
# 2:  Mick    WA       LA

DT2[DT1, nomatch=NA]
#    first state newstate
# 1:   Jim    CA       TX
# 2:  Mick    WA       LA
# 3:  Paul    OR       NA
# 4:   Ron    AZ       NA