【问题标题】:Partial replace/update on a data frame数据框的部分替换/更新
【发布时间】:2012-11-09 18:00:46
【问题描述】:

我有以下代码:

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

我想将dfV2 的值替换为partial_key 中与V1 列中匹配的相应值。不匹配的应该保持原样。

如果有一个完整的密钥,我会使用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

【问题讨论】:

    标签: r replace dataframe pattern-matching


    【解决方案1】:

    使用%in% 是不必要的,因为match 的输出已经包含该信息。所以你可以这样做:

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

    有时我希望 R 有一个类似于 Excel 的 IFERROR 的基本 if.na 函数。我在我的 Rprofile 中有它:

    if.na <- function(value, value.if.na) ifelse(is.na(value), value.if.na, value)
    df$V2 <- if.na(replacement, df$V2)
    

    【讨论】:

      【解决方案2】:

      您可以合并,然后进行所需的重新排列

      > 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
      

      【讨论】:

        【解决方案3】:

        另一种解决方案:

        comb <- rbind(df, partial_key)
        df$V2 <- head(ave(comb$V2, comb$V1,
                          FUN = function(x) tail(x, 1)), -nrow(partial_key))
        

        【讨论】:

          猜你喜欢
          • 2020-10-02
          • 1970-01-01
          • 2020-11-13
          • 1970-01-01
          • 2021-01-24
          • 1970-01-01
          • 1970-01-01
          • 2022-11-27
          • 2021-09-03
          相关资源
          最近更新 更多