Сравните строки и замените значение, если есть разница - PullRequest
0 голосов
/ 02 января 2019

Прежде всего: с Новым годом:)

Я борюсь с циклом, поэтому сейчас я ищу вашу помощь.

Ниже приведен короткий манекен:

df <- data.frame(name = c("a","a","b","b","c","d"), type = c(1,1,2,2,3,4), area = c("a","b","a","a","b","b"), length = c(10), power = c(10, 100))

Я бы хотел сравнить каждую уникальную комбинацию name, type и area и посмотреть, различаются ли length и power или нет.Если они этого не делают, я хочу сохранить их ценность;если они это сделают, я хочу заменить их значение на «Неизвестно».В приведенном выше примере, таким образом, будет только замена для name = b: length останется '10', но power станет 'Неизвестным'.В результате результирующий кадр данных будет иметь только пять строк.

Кажется, что это довольно простой цикл, но мне пока не удалось ... У вас есть идеи?

Приветствия,

Фред

Ответы [ 2 ]

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

С dplyr вы можете сделать:

df %>%
 group_by(name, type, area) %>%
 mutate(length = ifelse(length != first(length), "Unknown", paste0(length)),
        power = ifelse(power != first(power), "Unknown", paste0(power)))

  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     10     
4 b        2. a     10     Unknown
5 c        3. b     10     10     
6 d        4. b     10     100 

Проверяет, совпадают ли значения для первой строки для заданной комбинации «имя», «тип» и «область». Если нет, он заполняет строки значением «Неизвестно».

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

Я думаю, вам не нужен цикл 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...