根据行索引在列中附加值

时间:2019-11-10 21:00:04

标签: r

我想在列中添加新值,以使其他列在数据帧中重复与之对应的相同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 个答案:

答案 0 :(得分:2)

# 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 :(得分:1)

我们可以使用“总计”创建一列,然后绑定行

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

或使用uncountreplace扩展“ 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"))

答案 2 :(得分:0)

在基本R中,我们可以创建一个新的数据集,其中的ARMCD列已更改,并将rbind更改为原始数据框。然后,我们可以基于orderSUBJID

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

答案 3 :(得分:0)

1)ivot_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)嵌套使用dplyr / tidyr的另一种方法是将ARMCD列替换为一个列表,每个列表的元素都是由{{1 }},后跟等于“总计”的分量。然后ARMCD

unnest

给予:

library(dplyr)
library(tidyr)

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

2)基数R 定义一个函数# 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 ,该函数将获取行索引并返回重复的行,但第二行带有dupTotal移至每一行,并将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