R 在数据帧的每一行中找到一个最终值,保留该值,并替换所有其他值
我正在尝试在R中自动设置一些数据格式。按日期,我有多个位置的个人(每行是一个位置,因此一个人可能有多行)。我需要转换数据,以便每个位置日期都是一列,每个人有一行。如果在当天找到个人,则在列中输入1,否则输入0 完成后,我需要在每行中找到最后一个观察值,即1,将该值保留为1,但将该行中的所有其他值更改为0。我能够找到哪些行和列具有最终值,但我还没有找到如何将此函数包含到一个更大的语句中,该语句将查找这些值,然后替换不符合条件的行值。我不希望必须逐个替换每行中的值。我不需要输出告诉我哪些行/列符合我的条件。我需要找到它们的唯一原因是替换数据帧中的其他值。下面是我在phidot.org上找到的模拟数据代码,它帮助我构建了转置数据帧(由J Laake编写)。根据需要,创建“间隔”和“场合”以将bin位置划分为不同的时间段R 在数据帧的每一行中找到一个最终值,保留该值,并替换所有其他值,r,R,我正在尝试在R中自动设置一些数据格式。按日期,我有多个位置的个人(每行是一个位置,因此一个人可能有多行)。我需要转换数据,以便每个位置日期都是一列,每个人有一行。如果在当天找到个人,则在列中输入1,否则输入0 完成后,我需要在每行中找到最后一个观察值,即1,将该值保留为1,但将该行中的所有其他值更改为0。我能够找到哪些行和列具有最终值,但我还没有找到如何将此函数包含到一个更大的语句中,该语句将查找这些值,然后替换不符合条件的行值。我不希望必须逐个替换每行中的值。我不需要输出告诉我哪些行/列符合我
# create some dummy dates from tomorrow to 20 days from today
x = c(Sys.Date()+1:20)
# extract the year and change to numeric
as.numeric(format(x, "%Y"))
# you can also extract the month and day with
as.numeric(format(x, "%m"))
as.numeric(format(x, "%d"))
# create dummy capture data; id is animal and date is the date it was captured or recaptured
df=data.frame(id=floor(runif(100,1,50)),date=runif(100,0,5000)+as.Date("1980-01-01"))
#create some dummy date intervals that are approximately every 6 months
intervals=as.Date("1979-01-01")+seq(180,15*365,182.5)
# cut the dates into intervals
occasions=cut(df$date,intervals)
#create the count table with id for rows and years for columns
ch=with(df,table(id,occasions))
我得到下表(此处仅显示前10行和5列):
下面是我用来查找每行最后一个1并将其分配给对象的代码:
last <- apply(ch,1,function(x){tail(which(x==1),1)})
last
我想把桌子改成这样:
# id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29
# 1 0 1 0 0 0
# 2 0 0 0 1 0
# 3 0 0 0 0 1
# 4 0 0 0 0 0
# 5 0 0 0 1 0
# 6 0 0 0 1 0
# 7 0 1 0 0 0
# 9 0 0 0 0 1
# 10 0 0 0 0 1
我当前的转置数据帧“ch”是348行x 462列。每年都会添加数据,所以我想在R中自动化这个过程,而不是每年都要在Excel中格式化数据并将其放入R中进行分析。我在这个网站上以及phidot.org和互联网上查看了一些问题和答案,在花了几天的时间之后,我还没有弄明白这一点。提前感谢您的时间。我们可以在
数据表中轻松完成此操作。
-我没有创建中间矩阵,而是直接在data.frame中找到max行:
#replicate your data
df=data.frame(id=floor(runif(100,1,50)),date=runif(100,0,5000)+as.Date("1980-01-01"))
#create some dummy date intervals that are approximately every 6 months
intervals=as.Date("1979-01-01")+seq(180,15*365,182.5)
# cut the dates into intervals (I added this as a new column)
df$occasions = as.Date(as.character(cut(df$date,intervals)))
# convert to data.table
library(data.table)
setDT(df)
现在,我们可以找到每个id的最后日期:
df_last <- df[, .(last_date = max(occasions)), by = id]
然后,我们将其转换为所需的矩阵:
dcast(df_last, id ~ last_date, length, drop = FALSE, value.var = "last_date")
# Top Corner
id 1979-12-29 1980-06-29 1980-12-28 1981-06-29 1981-12-28 1982-06-29 1982-12-28
1: 1 0 0 0 0 0 0 0
2: 2 0 0 0 0 0 0 0
3: 3 0 0 0 0 0 0 0
4: 4 0 0 0 0 1 0 0
5: 5 0 1 0 0 0 0 0
6: 6 0 0 0 0 0 0 0
7: 7 0 0 0 0 0 0 0
8: 8 0 0 0 0 0 0 0
或者,从您停止使用表的位置开始构建并使用base R,您可以这样做
ch.new <- t(apply(ch, 1, function(row){row[which.max(cumsum(row))] <- "max"; ifelse(row=="max", 1, 0)}))
ch.new[1:6,]
occasions
id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29 1981-12-28 1982-06-29 1982-12-28 1983-06-29 1983-12-28 1984-06-28
1 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 1 0
5 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 1 0 0 0 0 0 0 0
8 0 0 0 1 0 0 0 0 0 0 0
occasions
id 1984-12-27 1985-06-28 1985-12-27 1986-06-28 1986-12-27 1987-06-28 1987-12-27 1988-06-27 1988-12-26 1989-06-27 1989-12-26
1 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 1 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0 0 0
occasions
id 1990-06-27 1990-12-26 1991-06-27 1991-12-26 1992-06-26 1992-12-25 1993-06-26
1 0 0 1 0 0 0 0
2 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0
5 0 0 0 0 0 1 0
6 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0
ch.new
df_last[, factor(as.character(last_date), levels = as.character(sort(unique(intervals))))]
dcast(df_last, id ~ last_date, length, drop = FALSE, value.var = "last_date")
# Top Corner
id 1979-12-29 1980-06-29 1980-12-28 1981-06-29 1981-12-28 1982-06-29 1982-12-28
1: 1 0 0 0 0 0 0 0
2: 2 0 0 0 0 0 0 0
3: 3 0 0 0 0 0 0 0
4: 4 0 0 0 0 1 0 0
5: 5 0 1 0 0 0 0 0
6: 6 0 0 0 0 0 0 0
7: 7 0 0 0 0 0 0 0
8: 8 0 0 0 0 0 0 0
ch.new <- t(apply(ch, 1, function(row){row[which.max(cumsum(row))] <- "max"; ifelse(row=="max", 1, 0)}))
ch.new[1:6,]
occasions
id 1979-06-30 1979-12-29 1980-06-29 1980-12-28 1981-06-29 1981-12-28 1982-06-29 1982-12-28 1983-06-29 1983-12-28 1984-06-28
1 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 1 0
5 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 1 0 0 0 0 0 0 0
8 0 0 0 1 0 0 0 0 0 0 0
occasions
id 1984-12-27 1985-06-28 1985-12-27 1986-06-28 1986-12-27 1987-06-28 1987-12-27 1988-06-27 1988-12-26 1989-06-27 1989-12-26
1 0 0 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 1 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 0 0 0
occasions
id 1990-06-27 1990-12-26 1991-06-27 1991-12-26 1992-06-26 1992-12-25 1993-06-26
1 0 0 1 0 0 0 0
2 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0
5 0 0 0 0 0 1 0
6 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0