【问题标题】:R: Replace multiple values in multiple columns of dataframes with values in another columnR:用另一列中的值替换数据框多列中的多个值
【发布时间】:2016-01-03 09:05:48
【问题描述】:

我正在尝试实现类似于 thisthis 问题的内容,但不是用单个值替换,而是我想根据另一列替换。

数据来自在特定日期进行测量时“是”的特定地点,我现在想要这些特定日期的河流水位。我的数据看起来像这样(但有更多的网站和日期):

date <- c('2000-01-01','2000-01-02','2000-01-03','2000-01-04','2000-01-05','2000-01-06','2000-01-07','2000-01-08','2000-01-09','2000-01-10')
date <- as.Date(date)
Site1 <- c('yes','','yes','','yes','','yes','','','')
Site2 <- c('yes','yes','yes','','','','','yes','','yes')
Site3 <- c('','','','','','','yes','yes','','yes')
waterlevel <- c(24,58,2,38,18,59,20,98,16,88)
df <- data.frame(date,Site1,Site2,Site3,waterlevel)

它给出了这个数据框:

         date Site1 Site2 Site3 waterlevel
1  2000-01-01   yes   yes               24
2  2000-01-02         yes               58
3  2000-01-03   yes   yes                2
4  2000-01-04                           38
5  2000-01-05   yes                     18
6  2000-01-06                           59
7  2000-01-07   yes         yes         20
8  2000-01-08         yes   yes         98
9  2000-01-09                           16
10 2000-01-10         yes   yes         88

我希望输出数据框如下所示:

         date Site1 Site2 Site3 waterlevel
1  2000-01-01   24   24              24
2  2000-01-02        58              58
3  2000-01-03    2    2               2
4  2000-01-04                        38
5  2000-01-05   18                   18
6  2000-01-06                        59
7  2000-01-07   20         20        20
8  2000-01-08         98   98        98
9  2000-01-09                        16
10 2000-01-10         88   88        88

我尝试使用上述问题的解决方案代码,并在不同的数据框中使用与水位匹配的参数,但解决方案不起作用:

sel <- grepl("Site",names(df))
df[sel] <- lapply(df[sel], function(x) replace(x,x %in% 2:4, df2$waterlevel[match(df$date,df2$date)]) )

任何帮助将不胜感激。

【问题讨论】:

    标签: r


    【解决方案1】:

    使用dplyr 你可以这样做:

    library("dplyr")
    df <- df %>% 
      mutate_at(vars(starts_with("Site")),
                function(x) ifelse(x == "yes", .$waterlevel, x))
    
    df
    #          date Site1 Site2 Site3 waterlevel
    # 1  2000-01-01    24    24               24
    # 2  2000-01-02          58               58
    # 3  2000-01-03     2     2                2
    # 4  2000-01-04                           38
    # 5  2000-01-05    18                     18
    # 6  2000-01-06                           59
    # 7  2000-01-07    20          20         20
    # 8  2000-01-08          98    98         98
    # 9  2000-01-09                           16
    # 10 2000-01-10          88    88         88
    

    【讨论】:

      【解决方案2】:

      使用data.table 包。在这里更容易处理长格式并再次昏迷回到宽格式(原始格式)。

      dcast(date+waterlevel~variable,   ## put again in the wide format
             data=melt(setDT(df),id=c("date","waterlevel"))[ ## long format
             value=="yes",value:=waterlevel]) ## filter and process one variable
      
               date waterlevel Site1 Site2 Site3
       1: 2000-01-01         24    24    24      
       2: 2000-01-02         58          58      
       3: 2000-01-03          2     2     2      
       4: 2000-01-04         38                  
       5: 2000-01-05         18    18            
       6: 2000-01-06         59                  
       7: 2000-01-07         20    20          20
       8: 2000-01-08         98          98    98
       9: 2000-01-09         16                  
      10: 2000-01-10         88          88    88
      

      【讨论】:

        【解决方案3】:
        df[sel] <- lapply(df[sel], 
                          function(x, value) ifelse(x == "yes", value, NA), 
                          value = df$waterlevel)
        
        #         date Site1 Site2 Site3 waterlevel
        #1  2000-01-01    24    24    NA         24
        #2  2000-01-02    NA    58    NA         58
        #3  2000-01-03     2     2    NA          2
        #4  2000-01-04    NA    NA    NA         38
        #5  2000-01-05    18    NA    NA         18
        #6  2000-01-06    NA    NA    NA         59
        #7  2000-01-07    20    NA    20         20
        #8  2000-01-08    NA    98    98         98
        #9  2000-01-09    NA    NA    NA         16
        #10 2000-01-10    NA    88    88         88
        

        【讨论】:

        • @PierreLafortune 为什么要将这些列变成类character
        • NA 更有意义。
        猜你喜欢
        • 2014-11-04
        • 2022-10-05
        • 2013-01-22
        • 2014-08-24
        • 2020-09-01
        • 2019-10-11
        • 1970-01-01
        • 2020-06-23
        • 2021-01-05
        相关资源
        最近更新 更多