2

私は次のコードを持っています:

set.seed(47)
df <- data.frame(V1 = sample(letters[1:5], size = 10, replace = TRUE),
                 V2 = 101:110)

partial_key <- data.frame(V1 = letters[1:3], V2 = 1:3)

> df
   V1  V2
1   e 101
2   b 102
3   d 103
4   e 104
5   c 105
6   d 106
7   b 107
8   c 108
9   c 109
10  e 110


> partial_key
  V1 V2
1  a  1
2  b  2
3  c  3

V2inの値を、列内で一致dfする対応する値に置き換えたいと思います。不一致はそのままにしておく必要があります。partial_keyV1

完全なキーでmatchは、正しい値を置き換えますが、一致しないものを。に置き換えNAます。

df[, "V2"] <- partial_key[match(df$V1, partial_key$V1), "V2"]
## Replaces too much

と一緒にソリューションをハックすることはできます%in%が、もっと良い方法はありますか?タイピングを減らして、より直感的なものはありますか?

df[df$V1 %in% partial_key$V1, "V2"] <-
partial_key[match(df$V1[df$V1 %in% partial_key$V1], partial_key$V1), "V2"]
## Works, but is there a better way?
> df
   V1  V2
1   e 101
2   b   2
3   d 103
4   e 104
5   c   3
6   d 106
7   b   2
8   c   3
9   c   3
10  e 110
4

3 に答える 3

4

%in%の出力にはmatchすでにその情報が含まれているため、使用する必要はありません。したがって、次のようなことができます。

replacement <- partial_key$V2[match(df$V1, partial_key$V1)]
df$V2 <- ifelse(is.na(replacement), df$V2, replacement)

Rif.naにExcelのような基本関数があればいいのにと思うことがありますIFERROR。私は自分のRprofileにそれを持っています:

if.na <- function(value, value.if.na) ifelse(is.na(value), value.if.na, value)
df$V2 <- if.na(replacement, df$V2)
于 2012-11-09T18:53:26.583 に答える
1

マージしてから、必要な再編成を行うことができます

> mdf <- merge(df, partial_key, by="V1", all.x=TRUE)
> mdf$V2.x[!is.na(mdf$V2.y)] <- mdf$V2.y[!is.na(mdf$V2.y)]
> mdf
   V1 V2.x V2.y
1   b    2    2
2   b    2    2
3   c    3    3
4   c    3    3
5   c    3    3
6   d  106   NA
7   d  103   NA
8   e  101   NA
9   e  104   NA
10  e  110   NA
> mdf[-3]
   V1 V2.x
1   b    2
2   b    2
3   c    3
4   c    3
5   c    3
6   d  106
7   d  103
8   e  101
9   e  104
10  e  110
于 2012-11-09T18:43:04.137 に答える
1

別の解決策:

comb <- rbind(df, partial_key)
df$V2 <- head(ave(comb$V2, comb$V1,
                  FUN = function(x) tail(x, 1)), -nrow(partial_key))
于 2012-11-09T19:37:52.563 に答える