我已经广泛研究了堆栈溢出的解决方案,但还没有找到适合我的解决方案。 我的数据框看起来像这样:
id time latitude longitude
A 11:10 381746.0 6008345
A 11:11 381726.2 6008294
B 10:56 381703.0 6008214
B 10:57 381679.7 6008134
C 4:30 381654.4 6008083
C 4:31 381629.2 6008033
我想在每个id的END处插入一个新行。在这一行中,我希望'id'和'time'与之前的观察相同。我希望纬度和经度为'394681.4'和'6017550'(对应于所有id的结束位置)。
id time latitude longitude
A 11:10 381746.0 6008345
A 11:11 381726.2 6008294
A 11:11 394681.4 6017550
B 10:56 381703.0 6008214
B 10:57 381679.7 6008134
B 10:57 394681.4 6017550
C 4:30 381654.4 6008083
C 4:31 381629.2 6008033
C 4:32 394681.4 6017550
有人能想到解决方案吗? Dplyr或数据表解决方案首选。
答案 0 :(得分:10)
我们可以使用data.table
执行此操作。将'data.frame'转换为'data.table'(setDT(df1)
),按'id'分组,使用tail
获取最后一行,使用new分配'latitude'和'longitude'值{,rbind
包含原始数据集,order
包含'id'。
library(data.table)
rbind(setDT(df1), df1[, tail(.SD, 1) , by = id
][, c("latitude", "longitude") := .(394681.4, 6017550)
])[order(id)]
# id time latitude longitude
#1: A 11:10 381746.0 6008345
#2: A 11:11 381726.2 6008294
#3: A 11:11 394681.4 6017550
#4: B 10:56 381703.0 6008214
#5: B 10:57 381679.7 6008134
#6: B 10:57 394681.4 6017550
#7: C 4:30 381654.4 6008083
#8: C 4:31 381629.2 6008033
#9: C 4:31 394681.4 6017550
或使用dplyr
,使用类似的方法
library(dplyr)
df1 %>%
group_by(id) %>%
summarise(time = last(time)) %>%
mutate(latitude = 394681.4, longitude = 6017550) %>%
bind_rows(df1, .) %>%
arrange(id)
答案 1 :(得分:2)
使用split-apply-combine概念的基础R解决方案。
do.call(rbind, lapply(split(df, df$id),
function(x) rbind(x,
within(x[nrow(x),], {latitude <- 394681.4; longitude <- 6017550}))))
返回
id time latitude longitude
A.1 A 11:10 381746.0 6008345
A.2 A 11:11 381726.2 6008294
A.21 A 11:11 394681.4 6017550
B.3 B 10:56 381703.0 6008214
B.4 B 10:57 381679.7 6008134
B.41 B 10:57 394681.4 6017550
C.5 C 4:30 381654.4 6008083
C.6 C 4:31 381629.2 6008033
C.61 C 4:31 394681.4 6017550
split
将data.frame分解为data.frames列表,lapply
rbind
是每个data.frame的最后一行,do.call
{{1}结果的data.frames列表。每个data.frame的最后一行是使用rbind
生成的,它返回给定的data.frame的修改版本。 within
用于选择最后一行。引用@ akrun的回答,nrow
可以替换为x[nrow(x),]
。
答案 2 :(得分:1)
使用dplyr
library(dplyr)
# data:
df <- structure(list(id = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("A",
"B", "C"), class = "factor"), time = structure(c(3L, 4L, 1L,
2L, 5L, 6L), .Label = c("10:56", "10:57", "11:10", "11:11", "4:30",
"4:31"), class = "factor"), latitude = c(381746, 381726.2, 381703,
381679.7, 381654.4, 381629.2), longitude = c(6008345L, 6008294L,
6008214L, 6008134L, 6008083L, 6008033L)), .Names = c("id", "time",
"latitude", "longitude"), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
# code:
df %>% group_by(id) %>%
do({ df <- .
last_row <- df %>% slice(n())
last_row$latitude <- 394681.4
last_row$longitude <- 6017550
df <- bind_rows(df, last_row)
})
答案 3 :(得分:0)
dplyr 方法
df1 %>%
group_by(id) %>%
slice_tail() %>%
bind_rows(df1) %>%
arrange(id,time)