G'全天,
我在R工作。抱歉这个非常基本的问题,但我有点卡住了。 我有一个存在/不存在点数数据的数据集,包括计数日期和站点编号(见下文)。我想最终创建一个data.frame,它按网格单元格数量整理所有计数,并且每次访问一个站点作为新访问(见下文)。我无法弄清楚如何做到这一点,所以我想我会采取一种更简单的方法,并制作一个列,为每条记录提供一个访问号码。因此,该列将根据每个站点组中的访问日期为每条记录提供一个数字(见下文)。我也无法弄清楚如何做到这一点! 任何帮助都会很棒,谢谢你。
亲切的问候, 亚当
我有这个:
Site date
1 12/01/2000
1 24/02/2000
1 13/08/2001
2 14/01/2000
2 21/01/2002
3 1/01/1999
3 21/04/2000
最终想要这个:
Site vist1 v2 v3
1 12/01/2000 24/02/2000 13/08/2001
2 14/01/2000 21/01/2002 na
3 01/01/1999 21/04/2000 na
但这会很好:
Site date visit
1 12/01/2000 1
1 24/02/2000 2
1 13/08/2001 3
2 14/01/2000 1
2 21/01/2002 2
3 01/01/1999 1
3 21/04/2000 2
答案 0 :(得分:2)
基本上,您希望将数据从长格式重新整形为宽格式,并且可以在一行中重复观察Site
。基本R函数reshape()
专为此任务而设计。
唯一(轻微)的复杂情况是,您首先需要添加一个列(我在此称之为obsNum
),该列标识Site
处的第一,第二,第三等观察。通过设置timevar = "obsNum"
,您可以让reshape()
知道要将date
的每个值放入哪一列。
df <- read.table(text = "Site date
1 12/01/2000
1 24/02/2000
1 13/08/2001
2 14/01/2000
2 21/01/2002
3 1/01/1999
3 21/04/2000", header=T, stringsAsFactors=FALSE)
df$obsNum <- unlist(sapply(rle(df$Site)$lengths, seq))
reshape(df, idvar="Site", timevar="obsNum", direction="wide")
# Site date.1 date.2 date.3
# 1 1 12/01/2000 24/02/2000 13/08/2001
# 4 2 14/01/2000 21/01/2002 <NA>
# 6 3 1/01/1999 21/04/2000 <NA>
答案 1 :(得分:0)
以下是ddply
和dcast
的其他解决方案。
library(reshape2)
# Convert the date column into actual dates
df$date <- as.Date(df$date, format="%d/%m/%Y")
# Ensure that the data.frame is sorted
df <- df[ order(df$site, df$date), ]
# Number the visits for each site
df$visit <- 1
d <- ddply(df, "Site", transform, visit=cumsum(visit))
# Convert to a wide format
# (Since dcast forgets the Date type, convert it to strings
# before and back to dates after.)
d$date <- as.character(d$date)
d <- dcast(d, Site ~ visit, value.var="date")
d[,-1] <- lapply(d[,-1], as.Date)
d
答案 2 :(得分:0)
以下是使用plyr
和reshape2
的解决方案的另一种观点。
require(plyr); require(reshape2); require(lubridate)
df <- ddply(df, .(Site), transform, visit = rank(dmy(date)))
dcast(df, Site ~ visit, value.var = 'date')