Я думаю, вам не нужен цикл for, но вы можете использовать duplicated
.Сначала найдите строки, которые имеют одинаковые значения name
, type
, area
и length
, но не имеют одинаковое значение мощности.Замените одно из значений power
на Unknown
df[which(duplicated(df[1:4]) & !duplicated(df[1:5])),'power'] <- 'Unkown'
Затем создайте новый кадр данных, который отбрасывает другую строку
df2 <- df[which(!duplicated(df[1:4],fromLast = T)),]
Вывод:
> df2
name type area length power
1 a 1 a 10 10
2 a 1 b 10 100
4 b 2 a 10 Unkown
5 c 3 b 10 10
6 d 4 b 10 100
РЕДАКТИРОВАТЬ : После дополнительных запросов от OP вот решение dplyr, которое работает для более общих случаев.
# New dataframe; containing multiple duplicates
df3 <- data.frame(name = c("a","a","b","b","b","c","d"),
type = c(1,1,2,2,2,3,4), area = c("a","b","a","a","a","b","b"),
length = rep(10,7),
power = c(10, 100, 10, 100,100,10,100))
df3 %>%
group_by(name, type, area) %>%
mutate(length = ifelse(n() > 1 && var(length) != 0, "Unknown", paste0(length)),
power = ifelse(n() > 1 && var(power) != 0, "Unknown", paste0(power)))
Функция сначала группирует по имени, типу и области.Затем он проверяет, существует ли более 1 строки, если это правда, он проверяет, меняются ли значения, если оба они истинны, он заменяет все значения на «Неизвестно».
Вывод:
# A tibble: 7 x 5
# Groups: name, type, area [5]
name type area length power
<fct> <dbl> <fct> <chr> <chr>
1 a 1 a 10 10
2 a 1 b 10 100
3 b 2 a 10 Unknown
4 b 2 a 10 Unknown
5 b 2 a 10 Unknown
6 c 3 b 10 10
7 d 4 b 10 100