Слияние двух столбцов в R с учетом других соответствующих столбцов?

#r #matrix #merge #multiple-columns

#r #матрица #слияние #несколько столбцов

Вопрос:

Я использую R и импортировал данные из 2 листов Excel, содержащих по 3 столбца в каждом. Первая матрица содержит 3 столбца (1-3) и 380 строк, а вторая матрица содержит 3 столбца и 365 строк. Столбцы 2 и 3 всегда являются значениями, соответствующими первому столбцу. Я хотел бы объединить первые столбцы двух матриц в один столбец таким образом, чтобы после слияния идентичные значения в двух столбцах просто заменялись (они не должны быть в отдельных строках один за другим), а столбец располагался в порядке возрастания. Кроме того, основным условием должно быть то, что столбцы 2,3 каждой матрицы (которые являются значениями для столбца 1) должны соответствующим образом переставляться, но не должны объединяться. Если в первом столбце есть некоторые значения (сгенерированные после слияния), значение которых отсутствует в соответствующем столбце, его следует заменить на ноль. Я выполнил слияние и перестановку для первого столбца, но я не могу внести соответствующие изменения в другие столбцы. Как мне обойти?

Вот две матрицы:

Матрица A

 92.6691     1076.5      0.48
93.324      1110.1      0.5
96.9597     1123.3      0.5
97.7539     968.4       0.43
98.992      1006.1      0.45
99.0061     5584.6      2.49
101.0243    1555.7      0.69
101.0606    12821.2     5.72
102.1221    972         0.43
  

Матрица B

 95.4466     974.2       0.43
99.0062     4721.9      2.06
100.0321    1040.1      0.45
101.0241    2115.8      0.92
101.0606    15202.8     6.64
102.2736    945.3       0.41
108.4273    1059.7      0.46
115.0397    25106.3     10.96
115.0761    54740       23.9
  

После слияния результаты должны представлять собой единую матрицу:

 Column 1 - Merged 1st columns of matrices A and B (ascending order)
Column 2 - Rearranged based on change in row positions of column 1 in matrix A
Column 3 - Rearranged based on change in row positions of column 1 in matrix A
Column 4 - Rearranged based on change in row positions of column 1 in matrix B
Column 5 - Rearranged based on change in row positions of column 1 in matrix B
  

Вот результирующая матрица:

 92.6691     1076.5      0.48      0        0
93.324      1110.1      0.5       0        0
95.4466     0           0         974.2    0.43
96.9597     1123.3      0.5       0        0
97.7539     968.4       0.43      0        0
98.992      1006.1      0.45      0        0
99.0061     5584.6      2.49      0        0
99.0062     0           0         4721.9   2.06
100.0321    0           0         1040.1   0.45
101.0241    0           0         2115.8   0.92
101.0243    1555.7      0.69      0        0
101.0606    12821.2     5.72      15202.8  6.64
102.1221    972         0.43      0        0
102.2736    0           0         945.3    0.41
108.4273    0           0         1059.7   0.46
115.0397    0           0         25106.3  10.96
115.0761    0           0         54740    23.9
  

Обратите внимание, что в матрицах A и B значение 101.0606 является общим.

Комментарии:

1. Не могли бы вы показать нам, что такое ввод и что такое вывод, на примере?

2. @discipulus Я обновил вопрос

3. Пожалуйста, покажите ожидаемый результат с предоставленными образцами данных. Описание не совсем понятно.

4. Что вы подразумеваете под «слиянием», поскольку столбец 1 состоит из числовых значений. Считаете ли вы 99.0061 и 99.0062 равными?

5. @UweBlock, нет, 99.0061 и 99.0062 должны быть друг за другом в одном столбце. Я добавлю, как должна выглядеть результирующая матрица

Ответ №1:

Это можно легко сделать с merge() помощью .

 # read your data:
read.table(
         t="92.6691     1076.5      0.48
            93.324      1110.1      0.5
            96.9597     1123.3      0.5
            97.7539     968.4       0.43
            98.992      1006.1      0.45
            99.0061     5584.6      2.49
            101.0243    1555.7      0.69
            101.0606    12821.2     5.72
            102.1221    972         0.43") -> M1
read.table(
         t="95.4466     974.2       0.43
            99.0062     4721.9      2.06
            100.0321    1040.1      0.45
            101.0241    2115.8      0.92
            101.0606    15202.8     6.64
            102.2736    945.3       0.41
            108.4273    1059.7      0.46
            115.0397    25106.3     10.96
            115.0761    54740       23.90") -> M2

# merge data -- note `all = TRUE` 
result <- merge(M1,M2,by = "V1", all = TRUE)

# replace na with 0
result[is.na(result)] <- 0

result
#        V1    V2.x V3.x    V2.y  V3.y
# 1   92.67  1076.5 0.48     0.0  0.00
# 2   93.32  1110.1 0.50     0.0  0.00
# 3   95.45     0.0 0.00   974.2  0.43
# 4   96.96  1123.3 0.50     0.0  0.00
# 5   97.75   968.4 0.43     0.0  0.00
# 6   98.99  1006.1 0.45     0.0  0.00
# 7   99.01  5584.6 2.49     0.0  0.00
# 8   99.01     0.0 0.00  4721.9  2.06
# 9  100.03     0.0 0.00  1040.1  0.45
# 10 101.02     0.0 0.00  2115.8  0.92
# 11 101.02  1555.7 0.69     0.0  0.00
# 12 101.06 12821.2 5.72 15202.8  6.64
# 13 102.12   972.0 0.43     0.0  0.00
# 14 102.27     0.0 0.00   945.3  0.41
# 15 108.43     0.0 0.00  1059.7  0.46
# 16 115.04     0.0 0.00 25106.3 10.96
# 17 115.08     0.0 0.00 54740.0 23.90
  

Комментарии:

1. Это было очень просто. Работает отлично 🙂

Ответ №2:

 df3 <- merge(df1,df2,all.x=T,all.y=T)
df3[is.na(df3)] <- 0

          x       a    b       c     d
1   92.6691  1076.5 0.48     0.0  0.00
2   93.3240  1110.1 0.50     0.0  0.00
3   95.4466     0.0 0.00   974.2  0.43
4   96.9597  1123.3 0.50     0.0  0.00
5   97.7539   968.4 0.43     0.0  0.00
6   98.9920  1006.1 0.45     0.0  0.00
7   99.0061  5584.6 2.49     0.0  0.00
8   99.0062     0.0 0.00  4721.9  2.06
9  100.0321     0.0 0.00  1040.1  0.45
10 101.0241     0.0 0.00  2115.8  0.92
11 101.0243  1555.7 0.69     0.0  0.00
12 101.0606 12821.2 5.72 15202.8  6.64
13 102.1221   972.0 0.43     0.0  0.00
14 102.2736     0.0 0.00   945.3  0.41
15 108.4273     0.0 0.00  1059.7  0.46
16 115.0397     0.0 0.00 25106.3 10.96
17 115.0761     0.0 0.00 54740.0 23.90
  

данные

 df1

x          a    b
92.6691   1076.5    0.48
93.324    1110.1    0.5
96.9597   1123.3    0.5
97.7539    968.4    0.43
98.992    1006.1    0.45
99.0061   5584.6    2.49
101.0243    1555.7  0.69
101.0606    12821.2 5.72
102.1221    972     0.43
df2
x              c    d
95.4466    974.2    0.43
99.0062   4721.9    2.06
100.0321    1040.1  0.45
101.0241    2115.8  0.92
101.0606    15202.8 6.64
102.2736    945.3   0.41
108.4273    1059.7  0.46
115.0397    25106.3 10.96
115.0761    54740   23.9
  

Ответ №3:

Я сам сгенерировал некоторые данные, вы можете заменить их своими. Здесь вам нужно будет объединить два файла; сначала по вертикали, а затем по горизонтали. Наконец, упорядочите их в соответствии с первым столбцом.

 set.seed(42)
# Load data 1
dat1<- as.data.frame(matrix(rexp(30), 10))

# Inly keep unique rows
dat1 <- unique(dat1)

set.seed(24)
# Load data 2
dat2 <-as.data.frame(matrix(rexp(30), 10))

# Inly keep unique rows
dat2 <- unique(dat2)

# Copy it in temp 
dat2n <-dat2

# sed second and third column to 0s
dat2n[,2:3] <- 0    
# Concatenate them and keep only unique
dat <- rbind(dat1,dat2n)

# Merge dat and dat2 with respect to column 1 and keep everything in dat

fin.dat <- merge(dat, dat2, by="V1", all.x = TRUE)

# Finally order the dataframe 
fin.dat <- fin.dat[order(fin.dat[,1], decreasing = FALSE),]
# Replace NA with zeros
fin.dat[is.na(fin.dat)] <- 0