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

Вопреки другим ответам, кажется, что если вы хотите получить +1, -1, +0 (для аргументов 1, -1, 0), вам нужно использовать формат:

String.Format("{0:+#;-#;+0}", 0));  // output: +0

или

String.Format("{0:+0;-#}", 0));  // output: +0

Если вы используете только +#;-#, он отобразит только + (не +0) для 0.

Пользовательский спецификатор «#» (в https://msdn.microsoft.com/en-us/library/0c899ak8.aspx )

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

blockquote>

Также учтите, что если вам нужна десятичная точность, вам нужно указать ее так:

String.Format("{0:+0.##;-#.##}", 0));  // output: +0

или, если вы не хотите, чтобы нули всегда отображались, например:

String.Format("{0:+0.00;-#.00}", 0));  // output: +0.00

0
задан nick 16 January 2019 в 19:49
поделиться

3 ответа

Один вариант с 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
ответ дан akrun 16 January 2019 в 19:49
поделиться

Вот решение, использующее 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
ответ дан Lyngbakr 16 January 2019 в 19:49
поделиться

Это можно сделать с помощью функций 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
0
ответ дан bouncyball 16 January 2019 в 19:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: