我有以下示例数据:
df <- data.frame(ID=c("A1","A2","A3","A4","A1","A2","A3","A4"),
NUM=c(469,586,394,595,398,203,604,809))
我正在寻找提取NUM列的第一个值并将其放置在新列NUM1中,然后在第二次出现具有相同ID的NUM值时,将该值提取到新列NUM2中。最后,我想删除原始列。除了ID和NUM,我拥有的数据集还有许多其他变量和列。以下是所需的输出。
df1 <- data.frame(ID=c("A1","A2","A3","A4"),NUM1=c(469,586,394,595),NUM2=c(398,203,604,809))
答案 0 :(得分:2)
这是一种方法。您将需要创建一个COL
列作为新列的名称,因此在这种情况下,我们使用group_by
和str_c
来创建此列。 pivot_wider
是spread
函数的更新版本。所有这些功能均来自tidyverse
软件包。
library(tidyverse)
df1 <- df %>%
group_by(ID) %>%
mutate(COL = str_c("NUM", row_number())) %>%
pivot_wider(names_from = COL, values_from = NUM) %>%
ungroup()
df1
# # A tibble: 4 x 3
# ID NUM1 NUM2
# <fct> <dbl> <dbl>
# 1 A1 469 398
# 2 A2 586 203
# 3 A3 394 604
# 4 A4 595 809
答案 1 :(得分:1)
使用基数R您可以:
reshape(transform(df,time=cumsum(grepl("1",ID))),idvar = "ID",dir="wide",sep="")
ID NUM1 NUM2
1 A1 469 398
2 A2 586 203
3 A3 394 604
4 A4 595 809
或者您可以尝试:
`colnames<-`(t(unstack(df,NUM~ID)),c("NUM1","NUM2"))
NUM1 NUM2
A1 469 398
A2 586 203
A3 394 604
A4 595 809
答案 2 :(得分:1)
@akrun雄辩的Base R解决方案:
df1 <- aggregate(NUM ~ ID, df, I)
(我的)Base R解决方案:
#Transform the dataframe:
df1 <- within(df, {
count_num_by_id <- ave(NUM, ID, FUN = seq.int);
NUM2 <- ifelse(count_num_by_id == 2, NUM, 0);
NUM <- ifelse(count_num_by_id == 1, NUM, 0);
rm(count_num_by_id)})
# Aggregate the dataframe:
df1 <- data.frame(aggregate(.~ID, df1, sum))
答案 3 :(得分:0)
您可以通过子设置获取每个ID
的第一个和第二个值
library(dplyr)
df %>%
group_by(ID) %>%
summarise(NUM1 = NUM[1L],
NUM2 = NUM[2L])
# A tibble: 4 x 3
# ID NUM1 NUM2
# <fct> <dbl> <dbl>
#1 A1 469 398
#2 A2 586 203
#3 A3 394 604
#4 A4 595 809
如果您要维护其他列,则可以使用mutate
library(dplyr)
df %>%
group_by(ID) %>%
mutate(NUM1 = NUM[1L],
NUM2 = NUM[2L]) %>%
slice(1L) %>%
select(-NUM)
答案 4 :(得分:0)
data.table
解决方案...
require(data.table)
# Set as a data.table and create a unique row.
setDT(df)[, rid := paste0('NUM', rowid(ID))]
# Cast the data by ID and rid.
df <- dcast(df, ID ~ rid, value.var = 'NUM')
df
# ID NUM1 NUM2
# 1: A1 469 398
# 2: A2 586 203
# 3: A3 394 604
# 4: A4 595 809
答案 5 :(得分:0)
这是一种alternative dcast()
方法,该方法直接在公式中调用rowid()
,还将处理df
中的其他列:
library(data.table)
dcast(setDT(df), ID + ... ~ rowid(ID, prefix = "NUM"), value.var = "NUM")
ID NUM1 NUM2 1: A1 469 398 2: A2 586 203 3: A3 394 604 4: A4 595 809
请注意prefix = "NUM"
的调用中的rowid()
参数。
df
中的其他列OP指出,他的数据集[...]除了ID和NUM 还有更多的变量和列。
如果 ,每个ID
的附加列的值都相同,那么+ ...
会将它们添加到输出中:
df2 <- data.frame(
ID = c("A1", "A2", "A3", "A4", "A1", "A2", "A3", "A4"),
NUM = c(469, 586, 394, 595, 398, 203, 604, 809),
other1 = rep(4:1, 2),
other2 = rep(letters[1:4], 2)
)
df2
ID NUM other1 other2 1 A1 469 4 a 2 A2 586 3 b 3 A3 394 2 c 4 A4 595 1 d 5 A1 398 4 a 6 A2 203 3 b 7 A3 604 2 c 8 A4 809 1 d
dcast(setDT(df2), ID + ... ~ rowid(ID, prefix = "NUM"), value.var = "NUM")
ID other1 other2 NUM1 NUM2 1: A1 4 a 469 398 2: A2 3 b 586 203 3: A3 2 c 394 604 4: A4 1 d 595 809