Как рассчитать построчное количество дубликатов на основе (поэлементно) выбранных соседних столбцов - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть фрейм данных test :

group userID A_conf A_chall B_conf B_chall
1    220      1       1      1       2     
1    222      4       6      4       4     
2    223      6       5      3       2     
1    224      1       5      4       4    
2    228      4       4      4       4    

Данные содержат ответы на пользователя ( показано userID ), где каждый пользователь может ввести любое значение междуОт 1 до 6 для обоих показателей:

  • conf
  • chall

Они также могут не отвечать, в результате чего NA запись.

test dataframe содержит несколько столбцов, таких как A, B, C, D и так далее.Для каждого из этих столбцов можно сообщать показатели Conf и Chall.

Я заинтересован в следующих сравнениях:

  • A_conf & A_chall
  • B_conf & B_chall

ЕСЛИ любые из этих мер равны, Final * Счетчик 1043 * должен быть увеличен (как показано ниже).

group userID A_conf A_chall B_conf B_chall Final
1    220      1       1      1       2     1
1    222      4       6      4       4     1
2    223      6       5      3       2     0
1    224      1       5      4       4     1
2    228      4       4      4       4     2

Я борюсь со счетчиком Final .Какой сценарий поможет мне достичь этой функциональности?

Для справки: dput из набора данных test представлен ниже:

  • dput (test):

    структура (список (группа = c (1L, 1L, 2L, 1L, 2L),

    userID = c (220L, 222L, 223L, 224L, 228L),

    A_conf = c (1L, 4L, 6L, 1L, 4L),

    A_chall = c (1L, 6L, 5L, 5L, 4L),

    B_conf = c (1L, 4L, 3L, 4L, 4L),

    B_chall = c (2L, 4L, 2L, 4L, 4L)),

    class = "data.frame", row.names= c (NA, -5L))

Я попробовал код, подобный следующему:

test$Final = as.integer(0)   # add a column to keep counts
count_inc = as.integer(0)    # counter variable to increment in steps of 1

for (i in 1:nrow(test)) {

    count_inc = 0

    if(!is.na(test$A_conf[i] == test$A_chall[i]))
    {
      count_inc = 1
      test$Final[i] = count_inc
    }#if

    else if(!is.na(test$A_conf[i] != test$A_chall[i]))
    {
      count_inc = 0
      test$Final[i] = count_inc
    }#else if
}#for

Приведенный выше код был написан для работы ТОЛЬКО с колонками A_conf и A_chall .Проблема в том, что он заполняет столбец Final всеми 1, независимо от того, равны ли введенные значения (пользователями) или нет.

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Вы также можете попробовать этот курс.Несколько меньше строк по сравнению с другим ответом;)

library(tidyverse)
d %>% 
  as.tibble() %>% 
  gather(k, v, -group,-userID) %>% 
  separate(k, into = c("letters", "test")) %>% 
  spread(test, v) %>% 
  group_by(userID) %>% 
  mutate(final = sum(chall == conf)) %>% 
  distinct(userID, final) %>% 
  ungroup() %>% 
  right_join(d)
# A tibble: 5 x 7
  userID final group A_conf A_chall B_conf B_chall
   <int> <int> <int>  <int>   <int>  <int>   <int>
1    220     1     1      1       1      1       2
2    222     1     1      4       6      4       4
3    223     0     2      6       5      3       2
4    224     1     1      1       5      4       4
5    228     2     2      4       4      4       4
0 голосов
/ 20 декабря 2018

Базовое решение R при условии, что у вас одинаковое количество столбцов "conf" и "chall"

#Find indexes of "conf" column
conf_col <- grep("conf", names(test))

#Find indexes of "chall" column
chall_col <- grep("chall", names(test))

#compare element wise and take row wise sum
test$Final <- rowSums(test[conf_col] == test[chall_col])


test
#  group userID A_conf A_chall B_conf B_chall Final
#1     1    220      1       1      1       2     1
#2     1    222      4       6      4       4     1
#3     2    223      6       5      3       2     0
#4     1    224      1       5      4       4     1
#5     2    228      4       4      4       4     2

Может также выполняться в один слой

rowSums(test[grep("conf", names(test))] == test[grep("chall", names(test))])
0 голосов
/ 20 декабря 2018

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

df %>%
 select(-Final) %>%
 rowid_to_column() %>% #Creating an unique row ID
 gather(var, val, -c(group, userID, rowid)) %>% #Reshaping the data
 arrange(rowid, var) %>% #Arranging by row ID and by variables
 group_by(rowid) %>% #Grouping by row ID
 mutate(temp = gl(n()/2, 2)) %>% #Creating a grouping variable for different "_chall" and "_conf" variables
 group_by(rowid, temp) %>% #Grouping by row ID and the new grouping variables
 mutate(res = ifelse(val == lag(val), 1, 0)) %>% #Comparing whether the different "_chall" and "_conf" have the same value
 group_by(rowid) %>% #Grouping by row ID
 mutate(res = sum(res, na.rm = TRUE)) %>% #Summing the occurrences of "_chall" and "_conf" being the same
 select(-temp) %>% 
 spread(var, val) %>% #Returning the data to its original form
 ungroup() %>%
 select(-rowid)

  group userID   res A_chall A_conf B_chall B_conf
  <int>  <int> <dbl>   <int>  <int>   <int>  <int>
1     1    220    1.       1      1       2      1
2     1    222    1.       6      4       4      4
3     2    223    0.       5      6       2      3
4     1    224    1.       5      1       4      4
5     2    228    2.       4      4       4      4
...