R: добавить столбец в фрейм данных, указывающий, повторяются ли значения строк в табличном объекте - PullRequest
0 голосов
/ 14 января 2020

У меня есть датафрейм и внешний вектор. Мне нужно посчитать повторяющиеся элементы в векторе (используя table() я думаю). Если эти значения находятся в кадре данных, мне нужно добавить это число в отдельные столбцы. Вот пример:

set.seed(5)
df1 = data.frame(numb = runif(5),
                 ID = c("a1", "a2", "a3", "a4", "a5"))


       numb ID
1 0.2002145 a1
2 0.6852186 a2
3 0.9168758 a3
4 0.2843995 a4
5 0.1046501 a5


# get external vector
vect1 = c("a1", "a1", "a5", "a1")

# count repetitive elements in a vector
my.tab <- table(vect1)
vect1
a1 a5 
 3  1 

Я знаю, что могу получить доступ к элементам объекта таблицы:

# get vector of table names
names(my.tab)
[1] "a1" "a5"

# get number of repetition
as.vector(my.tab)
[1] 3 1

Но как добавить эти значения в мой data.frame с помощью значение строки ? Я думал, что что-то подобное может работать:

df1$repID <- ifelse(df1$ID %in% vect1, 
                    if YES = add count from table, 
                    in NOT = add 1) # or any number

Ожидаемый результат :

       numb ID repID
1 0.4089769 a1  3
2 0.8830174 a2  1
3 0.9404673 a3  1
4 0.0455565 a4  1
5 0.5281055 a5  1

Ответы [ 3 ]

1 голос
/ 14 января 2020

Полное решение:

# the initial dataframe
set.seed(5)
df1 <- data.frame(numb = runif(5),
                 ID = c("a1", "a2", "a3", "a4", "a5"),
                 stringsAsFactors = FALSE)

# get external vector
vect1 <- c("a1", "a1", "a5", "a1")

# put this in a dataframe
df2 <- data.frame(ID = vect1, stringsAsFactors = FALSE)
df2 <- df2 %>%
    group_by(ID) %>% # group the dataframe
    summarise(repID = n()) # and then summarize over the groups

# and finally...
df1 %>% # take the original data frame
    left_join(df2, by = "ID") %>% # left join the aggregated data frame
    mutate(repID = replace_na(repID, 1)) # and then remove the NAs by 1s
1 голос
/ 14 января 2020

Вы можете использовать data.table.

Основная стратегия c заключается в создании двух data.table. Используйте группирование для подсчета вхождений значений во внешний вектор. Затем объедините эту таблицу сгруппированного счета и другую, используя полное объединение. Это даст нам NA там, где в соответствующих столбцах нет общих значений. Мы заполняем значения NA с помощью 1.

> library(data.table)

> my_count <- as.data.table(vect1)[, .(repID = .N), by = vect1] #  Using .N to count.
> dt <- setDT(df1)
> data <- merge(dt, my_count, by.x = "ID", by.y = "vect1", all = TRUE) #  Merge option all = TRUE is for a "full join". 
> setnafill(data, cols = "repID", fill = 1)

Выход:

> data
   ID      numb repID
1: a1 0.2002145     3
2: a2 0.6852186     1
3: a3 0.9168758     1
4: a4 0.2843995     1
5: a5 0.1046501     1

Если вы хотите, чтобы ваши окончательные данные были в качестве фрейма данных, используйте setDF.

1 голос
/ 14 января 2020

Мы можем использовать stack для преобразования именованного вектора из table в кадр данных, merge это с df1 и replace NA значениями с 1.

transform(merge(df1, stack(table(vect1)), by.x = "ID", by.y = "ind", all.x = TRUE), 
           values = replace(values, is.na(values), 1))

#  ID      numb values
#1 a1 0.2002145      3
#2 a2 0.6852186      1
#3 a3 0.9168758      1
#4 a4 0.2843995      1
#5 a5 0.1046501      1

Тот же лог c в tidyverse может быть реализован как

library(tidyverse)

left_join(df1, table(vect1) %>% enframe(), by = c('ID' = 'name')) %>%
          mutate(value = replace_na(value, 1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...