Как создать переменную, основанную на том, из какого фрейма данных получены значения в R? - PullRequest
0 голосов
/ 29 марта 2020

Я объединю следующие два 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 значение соответствует time в df1, тогда новая переменная (var1) будет записывать соответствующее значение freq, И 0, если для df1 такого значения time не существует.

  2. Где, если значение freq соответствует time в df2, тогда вторая новая переменная (var2) будет записывать это freq значение из df2, И 0 если бы не было time значения, существующего для df2.

Итак, у меня была бы следующая таблица:

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
...

Ответы [ 3 ]

1 голос
/ 29 марта 2020

Код - база 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)
1 голос
/ 29 марта 2020

Если бы я понял, как правильно выглядит ваш фрейм данных (что-то, что будет создано через:)

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)}))

Надеюсь, это поможет,

0 голосов
/ 29 марта 2020

Более простой подход с использованием tidyverse или dplyr:

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
...