Добавление значений в столбец в соответствии с индексом строки - PullRequest
0 голосов
/ 11 ноября 2019

Я хочу добавить новое значение в столбец таким образом, чтобы другие столбцы повторяли то же самое values(Duplicates), соответствующее ему во фрейме данных:

test <- sqldf("select SUBJID, SITEID, ARMCD from dm where ARMCD !='' ")

test

 SUBJID SITEID    ARMCD
1 102-S0001    102 SER401_A
2 102-S0002    102 SER401_A
3 102-S0003    102 SER401_P
4 102-S0005    102 SER401_A
5 102-S0006    102 SER401_A
6 107-S0002    107 SER401_A
7 108-S0002    108 SER401_A
8 108-S0004    108 SER401_P

Требуемый вывод должен быть таким

    SUBJID    SITEID    ARMCD
1  102-S0001    102   SER401_A
2  102-S0001    102    Total
3  102-S0002    102   SER401_A
4  102-S0001    102    Total
5  102-S0003    102   SER401_P
6  102-S0003    102    Total
7  102-S0005    102   SER401_A
8  102-S0005    102    Total
9  102-S0006    102   SER401_A
10 102-S0006    102    Total
11 107-S0002    107   SER401_A
12 107-S0002    107    Total
13 108-S0002    108   SER401_A
14 108-S0002    108     Total
15 108-S0004    108   SER401_P
16 108-S0004    108    Total

Буду благодарен, если смогу получить код r для вышеприведенного вывода.

Ответы [ 4 ]

2 голосов
/ 11 ноября 2019
# convert test to data.table
library(data.table)
setDT(test)

Дублирование строк и изменение ARMCD

# duplicate each row
test[rep(1:.N, each = 2) 
# replace every other row with 'Total'   
     ][, ARMCD := replace(ARMCD, !!(.I - 1) %% 2, 'Total')][]

Или rbind и изменение порядка

rbind(test, copy(test)[, ARMCD := 'Total']
      )[test[, c(rbind(1:.N, .N + 1:.N))]]

Вывод

#        SUBJID SITEID    ARMCD
#  1: 102-S0001    102 SER401_A
#  2: 102-S0001    102    Total
#  3: 102-S0002    102 SER401_A
#  4: 102-S0002    102    Total
#  5: 102-S0003    102 SER401_P
#  6: 102-S0003    102    Total
#  7: 102-S0005    102 SER401_A
#  8: 102-S0005    102    Total
#  9: 102-S0006    102 SER401_A
# 10: 102-S0006    102    Total
# 11: 107-S0002    107 SER401_A
# 12: 107-S0002    107    Total
# 13: 108-S0002    108 SER401_A
# 14: 108-S0002    108    Total
# 15: 108-S0004    108 SER401_P
# 16: 108-S0004    108    Total
1 голос
/ 11 ноября 2019

Мы можем создать столбец с помощью «Всего» и затем связать строки

library(dplyr)
df1 %>% 
   mutate(ARMCD = 'Total', rn = row_number()) %>% 
   bind_rows(df1 %>% 
                mutate(rn = row_number())) %>% 
   arrange(rn, ARMCD) %>% 
   select(-rn)
#    SUBJID SITEID    ARMCD
#1  102-S0001    102 SER401_A
#2  102-S0001    102    Total
#3  102-S0002    102 SER401_A
#4  102-S0002    102    Total
#5  102-S0003    102 SER401_P
#6  102-S0003    102    Total
#7  102-S0005    102 SER401_A
#8  102-S0005    102    Total
#9  102-S0006    102 SER401_A
#10 102-S0006    102    Total
#11 107-S0002    107 SER401_A
#12 107-S0002    107    Total
#13 108-S0002    108 SER401_A
#14 108-S0002    108    Total
#15 108-S0004    108 SER401_P
#16 108-S0004    108    Total

или расширить набор данных с помощью uncount и replace значений в 'ARMCD'

library(tidyr)
df1 %>%
  uncount(2) %>% 
  mutate(ARMCD = replace(ARMCD,  seq(1, n(), by = 2), 'Total'))

данные

df1 <- structure(list(SUBJID = c("102-S0001", "102-S0002", "102-S0003", 
"102-S0005", "102-S0006", "107-S0002", "108-S0002", "108-S0004"
), SITEID = c(102L, 102L, 102L, 102L, 102L, 107L, 108L, 108L), 
    ARMCD = c("SER401_A", "SER401_A", "SER401_P", "SER401_A", 
    "SER401_A", "SER401_A", "SER401_A", "SER401_P")), 
    class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8"))
0 голосов
/ 11 ноября 2019

1) pivot_longer Вставьте столбец A2, все строки которого содержат слово Total, а затем измените его с широкой на длинную форму, используя pivot_longer. Это также создаст столбец name, который нам не нужен, поэтому удалите его.

library(dplyr)
library(tidyr)

test %>%
  mutate(A2 = "Total") %>%
  pivot_longer(starts_with("A"), values_to = "ARMCD") %>%
  select(-name)

, что дает:

# A tibble: 16 x 3
   SUBJID    SITEID ARMCD   
   <chr>      <int> <chr>   
 1 102-S0001    102 SER401_A
 2 102-S0001    102 Total   
 3 102-S0002    102 SER401_A
 4 102-S0002    102 Total   
 5 102-S0003    102 SER401_P
 6 102-S0003    102 Total   
 7 102-S0005    102 SER401_A
 8 102-S0005    102 Total   
 9 102-S0006    102 SER401_A
10 102-S0006    102 Total   
11 107-S0002    107 SER401_A
12 107-S0002    107 Total   
13 108-S0002    108 SER401_A
14 108-S0002    108 Total   
15 108-S0004    108 SER401_P
16 108-S0004    108 Total   

1a) unnest Другой способиспользуйте dplyr / tidyr для замены столбца ARMCD списком, каждый элемент которого представляет собой двухвекторный элемент, состоящий из элемента ARMCD, за которым следует компонент, равный «Всего». Затем unnest that.

library(dplyr)
library(tidyr)

test %>%
  rowwise %>%
  mutate(ARMCD = list(c(ARMCD, "Total"))) %>%
  ungroup %>%
  unnest(ARMCD)

, что дает:

# A tibble: 16 x 3
   SUBJID    SITEID ARMCD   
   <chr>      <int> <chr>   
 1 102-S0001    102 SER401_A
 2 102-S0001    102 Total   
 3 102-S0002    102 SER401_A
 4 102-S0002    102 Total   
 5 102-S0003    102 SER401_P
 6 102-S0003    102 Total   
 7 102-S0005    102 SER401_A
 8 102-S0005    102 Total   
 9 102-S0006    102 SER401_A
10 102-S0006    102 Total   
11 107-S0002    107 SER401_A
12 107-S0002    107 Total   
13 108-S0002    108 SER401_A
14 108-S0002    108 Total   
15 108-S0004    108 SER401_P
16 108-S0004    108 Total

2) Base R Определить функцию dup, которая принимает индекс строки и возвращаетстрока дублируется, но с Total во втором ряду. sapply для каждой строки и rbind результатов вместе.

dup <- function(i) {
  test <- test[c(i, i), ]
  test$ARMCD[2] <- "Total"
  test
}  
do.call("rbind", lapply(1:nrow(test), dup))

, дающих:

       SUBJID SITEID    ARMCD
1   102-S0001    102 SER401_A
1.1 102-S0001    102    Total
2   102-S0002    102 SER401_A
2.1 102-S0002    102    Total
3   102-S0003    102 SER401_P
3.1 102-S0003    102    Total
4   102-S0005    102 SER401_A
4.1 102-S0005    102    Total
5   102-S0006    102 SER401_A
5.1 102-S0006    102    Total
6   107-S0002    107 SER401_A
6.1 107-S0002    107    Total
7   108-S0002    108 SER401_A
7.1 108-S0002    108    Total
8   108-S0004    108 SER401_P
8.1 108-S0004    108    Total

Примечание

Предполагается, что ввод в воспроизводимом видебыть:

Lines <- "
     SUBJID SITEID    ARMCD
1 102-S0001    102 SER401_A
2 102-S0002    102 SER401_A
3 102-S0003    102 SER401_P
4 102-S0005    102 SER401_A
5 102-S0006    102 SER401_A
6 107-S0002    107 SER401_A
7 108-S0002    108 SER401_A
8 108-S0004    108 SER401_P"
test <- read.table(text = Lines, as.is = TRUE)
0 голосов
/ 11 ноября 2019

В базе R мы можем создать новый набор данных с измененным столбцом ARMCD и rbind к исходному фрейму данных. Затем мы можем order новый фрейм данных на основе SUBJID и SITEID

order_df <- rbind(test, transform(test, ARMCD = "Total"))
order_df[with(order_df, order(SUBJID, SITEID)), ]

#      SUBJID SITEID    ARMCD
#1  102-S0001    102 SER401_A
#11 102-S0001    102    Total
#2  102-S0002    102 SER401_A
#21 102-S0002    102    Total
#3  102-S0003    102 SER401_P
#31 102-S0003    102    Total
#4  102-S0005    102 SER401_A
#41 102-S0005    102    Total
#5  102-S0006    102 SER401_A
#51 102-S0006    102    Total
#6  107-S0002    107 SER401_A
#61 107-S0002    107    Total
#7  108-S0002    108 SER401_A
#71 108-S0002    108    Total
#8  108-S0004    108 SER401_P
#81 108-S0004    108    Total
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...