【问题标题】:How to create variable that is based on which data frame the values came from in R?如何根据值来自 R 中的哪个数据框创建变量?
【发布时间】:2020-03-29 15:59:41
【问题描述】:

我将按时间升序合并以下两个df,不重复。 我的目标是还有两个新变量。

df1
   time   freq                  
1   1.5    1
2   3.5    1
3   4.5    2
4   5.5    1
5   8.5    2
6   9.5    1
7  10.5    1
8  11.5    1
9  15.5    1
10 16.5    1
11 18.5    1
12 23.5    1
13 26.5    1

df2
  time freq
1  0.5    6
2  2.5    2
3  3.5    1
4  6.5    1
5 15.5    1

请帮助我创建两个新列的代码:

  1. 如果freq 值对应于df1 中的time,则新变量(var1) 将记录关联的freq 值,如果没有这样的@,则0 df1 存在 987654329@ 值。

  2. 如果freq 值对应于df2 中的time,那么第二个新变量(var2)将记录来自df2freq 值,AND 0如果df2 不存在这样的time 值。

所以我会有一个像下面这样的表格:

time var1 var2
0.5   0    6
1.5   1    0
2.5   0    2
3.5   1    1
4.5   2    0
5.5   1    0
...

【问题讨论】:

标签: r dataframe statistics data-manipulation


【解决方案1】:

如果我正确理解了您的数据框的外观(可以通过以下方式创建:)

df1 = data.frame(time = c(1.5, 3.5, 4.5, 5.5, 8.5, 9.5, 10.5, 11.5, 15.5, 16.5, 18.5, 23.5, 26.5), freq = c(1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1))
df2 = data.frame(time = c(0.5, 2.5, 3.5, 6.5, 15.5), freq = c(6, 2, 1, 1, 1))

然后你会得到你正在寻找的东西:

df_new = data.frame(time = sort(unique(c(df1$time, df2$time))), var1 = sapply(sapply(time, function(x) {df1$freq[df1$time == x]}), function(x) {ifelse(length(x) == 0, 0, x)}), var2 = sapply((sapply(time, function(x) {df2$freq[df2$time == x]})), function(x) {ifelse(length(x) == 0, 0, x)}))

希望这会有所帮助,

【讨论】:

    【解决方案2】:

    代码 - 基础 R

    df3 <- merge(x = df1, df2, by.x = 'time', by.y = 'time', all = TRUE, sort = TRUE)
    df3$freq.x[is.na(df3$freq.x)] <- 0
    df3$freq.y[is.na(df3$freq.y)] <- 0
    

    代码 - data.table 库

    library('data.table')
    setDT(df1)  
    setkey(df1, time)
    df3 <- merge(x = df1, df2, all = TRUE, sort = TRUE)
    df3[is.na(freq.x), freq.x := 0 ]
    df3[is.na(freq.y), freq.y := 0 ]
    

    输出

    df3
    #    time freq.x freq.y
    # 1:  0.5      0      6
    # 2:  1.5      1      0
    # 3:  2.5      0      2
    # 4:  3.5      1      1
    # 5:  4.5      2      0
    # 6:  5.5      1      0
    # 7:  6.5      0      1
    # 8:  8.5      2      0
    # 9:  9.5      1      0
    # 10: 10.5      1      0
    # 11: 11.5      1      0
    # 12: 15.5      1      1
    # 13: 16.5      1      0
    # 14: 18.5      1      0
    # 15: 23.5      1      0
    # 16: 26.5      1      0
    

    数据

    df1 <- read.table(text = 
    'time   freq                  
    1   1.5    1
    2   3.5    1
    3   4.5    2
    4   5.5    1
    5   8.5    2
    6   9.5    1
    7  10.5    1
    8  11.5    1
    9  15.5    1
    10 16.5    1
    11 18.5    1
    12 23.5    1
    13 26.5    1', header = TRUE, stringsAsFactor = FALSE)
    
    df2 <- read.table(text = 
    'time freq
    1  0.5    6
    2  2.5    2
    3  3.5    1
    4  6.5    1
    5 15.5    1', header = TRUE, stringsAsFactor = FALSE)
    

    【讨论】:

      【解决方案3】:

      使用tidyversedplyr 的更直接的方法:

      library(tidyverse)
      
      df1 <- tibble(time = c(1.5, 3.5, 4.5, 5.5), freq = c(1, 1, 2, 1))
      df2 <- tibble(time = c(0.5, 2.5, 3.5, 6.5), freq = c(6, 2, 1, 1))
      
      full_join(df1, df2, by = "time", suffix = c("_1", "_2")) %>% 
        mutate_all(~ .x %>% replace_na(0)) %>% 
        arrange(time)
      
      # A tibble: 7 x 3
         time freq_1 freq_2
        <dbl>  <dbl>  <dbl>
      1   0.5      0      6
      2   1.5      1      0
      3   2.5      0      2
      4   3.5      1      1
      5   4.5      2      0
      6   5.5      1      0
      7   6.5      0      1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-13
        • 2021-01-21
        • 1970-01-01
        相关资源
        最近更新 更多