我有一个带有以下变量的数据框:
date=c("30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018")
hour=c(1,1,1,1,2,2,2,2)
location=c(North,South,East,West,North,South,East,West)
North=c(10,30,40,50,0,40,31,11)
South=c(20,10,20,0,0,0,5,0)
East=c(0,10,10,5,0,0,5,0)
West=c(5,30,40,50,0,40,31,11)
df <- data.frame(date, hour, location, North, South, East, West)
location
代表观察结果的位置。 North
,South
,East
和West
列显示了这些地区的平均降雨量。首先,我需要创建一列Actual
来描述location
中的降雨量。例如,对于第1行,Actual
的值将为10,因为它位于北方。接下来,我需要创建另外两列High1
和High2
。前者代表该小时内其余3个地区的最高降雨量,后者代表其余3个地区的第二高降雨量。例如,对于第1行,High1
和High2
的值分别为20和5,因为在该小时中,南方和西方的记录值最高,第二高。
是否存在可以用于此设置的推荐命令?谢谢。
答案 0 :(得分:1)
尝试一下(我相信有很多更简单的解决方案):
name a b
0 anthony 10 5
1 marcus 25 0
2 paul 0 0
3 Aaron 200 7
数据
import pandas as pd
from io import StringIO
s = '''\
name,a,b
anthony,10,5
marcus,75,-50
paul,100,-100
Aaron,200,7
'''
df = pd.read_csv(StringIO(s))
答案 1 :(得分:1)
您可以使用以下代码,该代码使用 Rfast 包中的nth
函数来获取其余地区的第二高降雨量。
library(Rfast)
NSEW <- grep("North|South|East|West", names(df))
i.col <- sapply(df$location, function(x) grep(x, names(df)))
df$Actual <- as.numeric(df[cbind(1:nrow(df), i.col)])
df[cbind(1:nrow(df), i.col)] <- 0
df$High1 <- apply(df[,NSEW], 1, max) # *
df$High2 <- apply(df[,NSEW], 1, Rfast::nth, k=2, descending=TRUE) # *
df[cbind(1:nrow(df), i.col)] <- df$Actual
df
date hour location North South East West Actual High1 High2
1 30/03/2018 1 North 10 20 0 5 10 20 5
2 30/03/2018 1 South 30 10 10 30 10 30 30
3 30/03/2018 1 East 40 20 10 40 10 40 40
4 30/03/2018 1 West 50 0 5 50 50 50 5
5 30/03/2018 2 North 0 0 0 0 0 0 0
6 30/03/2018 2 South 40 0 0 40 0 40 40
7 30/03/2018 2 East 31 5 5 31 5 31 31
8 30/03/2018 2 West 11 0 0 11 11 11 0
*也可以使用rownth
,它返回每一行的第n个最小值:
df$High1 <- Rfast::rownth(as.matrix(df[,NSEW]), elems=rep(1, nrow(df)), descending=TRUE)
df$High2 <- Rfast::rownth(as.matrix(df[,NSEW]), elems=rep(2, nrow(df)), descending=TRUE)
答案 2 :(得分:0)
如果您不想使用tidyverse,可以选择以下方法:
date <- c("30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018","30/03/2018")
hour <- c(1,1,1,1,2,2,2,2)
loc <- c("North","South","East","West","North","South","East","West")
North <- c(10,30,40,50,0,40,31,11)
South <- c(20,10,20,0,0,0,5,0)
East <- c(0,10,10,5,0,0,5,0)
West <- c(5,30,40,50,0,40,31,11)
location <- list(North, South, East, West, North, South, East, West)
actual <- numeric(length(location))
High1 <- numeric(length(location))
High2 <- numeric(length(location))
for (i in 1:length(location)){
actual[i] <- (location[[i]][i])
location[[i]][i] <- 0
High1[i] <- max(sapply(location , `[` , i))
}
short_location <- location[c(1:4)]
for (i in 1:length(location)){
n <- length(short_location)
High2[i] <- sort(sapply(short_location , `[` , i), partial=n-1)[n-1]
}
df <- data.frame(date, hour, loc, North, South, East, West, actual, High1, High2)