Как изменить элемент столбца на основе изменения значения в другом столбце в R - PullRequest
0 голосов
/ 16 января 2019

У меня есть следующие данные:

1   2   1           
2   3   1           
3   4   1           
4   5   1           
5   6   2           
6   7   2           
7   8   2                       
9   10  3           
10  11  3           

.. и я хочу изменить элемент второго столбца на основе изменения значения третьего столбца, чтобы получить это:

1   2   1           
2   3   1           
3   4   1           
4   1   1           
5   6   2           
6   7   2           
7   5   2                       
9   10  3           
10  9   3               

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

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Вот решение, которое использует rle и cumsum для определения индексов элементов, которые необходимо обновить в столбце 2.

# Create data frame
df <- read.table(text = "1   2   1           
2   3   1           
3   4   1           
4   5   1           
5   6   2           
6   7   2           
7   8   2                       
9   10  3           
10  11  3    ", header = FALSE)

# Create index
ind <- cumsum(rle(df$V3)$lengths) 

# Update data frame
df[ind, 2] <- df[head(c(1, ind + 1), length(ind)), 1]

# Print result
print(df)
#>   V1 V2 V3
#> 1  1  2  1
#> 2  2  3  1
#> 3  3  4  1
#> 4  4  1  1
#> 5  5  6  2
#> 6  6  7  2
#> 7  7  5  2
#> 8  9 10  3
#> 9 10  9  3

Создано в 2019-01-16 с помощью пакета Представить (v0.2.1)

0 голосов
/ 17 января 2019

Один вариант с rleid из data.table. После преобразования в data.table (setDT(df)) сгруппируйте по идентификатору длины прогона «V3», replace последний элемент «V2» с first для «V1» и назначьте (:= ) это к 'V2'

library(data.table)
setDT(df)[, V2 := replace(V2, .N, first(V1)), rleid(V3)]
df
#   V1 V2 V3
#1:  1  2  1
#2:  2  3  1
#3:  3  4  1
#4:  4  1  1
#5:  5  6  2
#6:  6  7  2
#7:  7  5  2
#8:  9 10  3
#9: 10  9  3

Данные

df <- structure(list(V1 = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 9L, 10L), V2 = c(2L, 
 3L, 4L, 5L, 6L, 7L, 8L, 10L, 11L), V3 = c(1L, 1L, 1L, 1L, 2L, 
   2L, 2L, 3L, 3L)), class = "data.frame", row.names = c(NA, -9L
  ))
0 голосов
/ 16 января 2019

Это можно сделать с помощью функций split, unsplit и lapply. Мы заменяем последнее значение во втором столбце первым значением в первом столбце для каждой группы значений V3. Функция split берет data.frame и превращает его в список данных.

unsplit(lapply(split(dat, dat$V3), 
               FUN = function(d) {d[nrow(d), 2] <- d[1,1]; d}))

  V1 V2 V3
1  1  2  1
2  2  3  1
3  3  4  1
4  4  1  1
5  5  6  2
6  6  7  2
7  7  5  2
8  9 10  3
9 10  9  3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...