조건부('if') 문을 기준으로 데이터 프레임의 값 바꾸기
아래에 대해 코드화된 R 데이터 프레임에서, 나는 모든 시간을 대체하고 싶습니다.B
와 함께 표시됩니다.b
.
junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12])
colnames(junk) <- c("nm", "val")
이 기능은 다음과 같습니다.
nm val
1 A a
2 B b
3 C c
4 D d
5 A e
6 B f
7 C g
8 D h
9 A i
10 B j
11 C k
12 D l
제가 처음 시도한 것은for
그리고.if
다음과 같은 문장:
for(i in junk$nm) if(i %in% "B") junk$nm <- "b"
하지만 보시다시피, 이것은 모든 가치를 대체합니다.junk$nm
와 함께b
나는 이것이 왜 이것을 하는지 알 수 있지만 나는 그것이 원래 값이었던 정크 $nm의 경우만 대체하도록 할 수 없는 것 같습니다.B
.
참고: 문제를 해결할 수 있었습니다.gsub
하지만 R을 배우는 것을 위해 저는 여전히 제 독창적인 접근법을 얻는 방법을 알고 싶습니다 (가능하다면).
nm를 문자로 변환한 다음 변경하기가 더 쉽습니다.
junk$nm <- as.character(junk$nm)
junk$nm[junk$nm == "B"] <- "b"
편집: 실제로 nm를 요인으로 유지해야 하는 경우 마지막에 다음을 추가합니다.
junk$nm <- as.factor(junk$nm)
가치를 대체하는 또 다른 유용한 방법
library(plyr)
junk$nm <- revalue(junk$nm, c("B"="b"))
간단한 대답은 다음과 같습니다.
junk$nm[junk$nm %in% "B"] <- "b"
R 서론에서 인덱스 벡터를 살펴봅니다(아직 읽지 않은 경우).
편집. 주석에서 알 수 있듯이 이 솔루션은 문자 벡터에 대해 작동하므로 데이터에서 실패합니다.
요인의 경우 가장 좋은 방법은 수준을 변경하는 것입니다.
levels(junk$nm)[levels(junk$nm)=="B"] <- "b"
당신이 보여주는 데이터는 요인들이기 때문에, 그것은 상황을 조금 복잡하게 만듭니다.@diliop의 답변은 다음과 같이 변환하여 문제에 접근합니다.nm
문자 변수로 변환합니다.원래 요인으로 돌아가려면 추가 단계가 필요합니다.
또 다른 방법은 요인의 수준을 조정하는 것입니다.
> lev <- with(junk, levels(nm))
> lev[lev == "B"] <- "b"
> junk2 <- within(junk, levels(nm) <- lev)
> junk2
nm val
1 A a
2 b b
3 C c
4 D d
5 A e
6 b f
7 C g
8 D h
9 A i
10 b j
11 C k
12 D l
그것은 매우 간단하고 나는 종종 그것에 대한 대체 기능이 있다는 것을 잊습니다.levels()
.
편집: @Seth가 코멘트에서 언급한 것처럼, 명확성을 잃지 않고 한 줄로 수행할 수 있습니다.
within(junk, levels(nm)[levels(nm) == "B"] <- "b")
하나의 명령으로 이 작업을 수행하는 가장 쉬운 방법은which
명령을 사용하여 요인을 문자로 변경할 필요가 없습니다.
junk$nm[which(junk$nm=="B")]<-"b"
다음에서 요인 변수를 만들었습니다.nm
따라서 이를 피하거나 요인 속성에 수준을 추가해야 합니다.또한 사용을 피해야 합니다.<-
data.frame에 대한 인수에 있습니다.
옵션 1:
junk <- data.frame(x = rep(LETTERS[1:4], 3), y =letters[1:12], stringsAsFactors=FALSE)
junk$nm[junk$nm == "B"] <- "b"
옵션 2:
levels(junk$nm) <- c(levels(junk$nm), "b")
junk$nm[junk$nm == "B"] <- "b"
junk
사용할 수 있습니다.ifelse
또한, 그것은 이해하기 매우 간단합니다.
junk$val <- ifelse(junk$nm == "B", "b", junk$val)
그래도 끝까지 해내고 싶다면,for loop
그것을 하는 올바른 방법
for(i in 1:nrow(junk)){
if(junk[i, "nm"] == "B"){
junk[i, "val"] <- "b"
}
}
junk
> junk
nm val
1 A a
2 B b
3 C c
4 D d
5 A e
6 B b
7 C g
8 D h
9 A i
10 B b
11 C k
12 D l
문자 변수로 작업하는 경우(참고:stringsAsFactors
여기서는 false입니다). 바꾸기를 사용할 수 있습니다.
junk <- data.frame(x <- rep(LETTERS[1:4], 3), y <- letters[1:12], stringsAsFactors = FALSE)
colnames(junk) <- c("nm", "val")
junk$nm <- replace(junk$nm, junk$nm == "B", "b")
junk
# nm val
# 1 A a
# 2 b b
# 3 C c
# 4 D d
# ...
저도 같은 문제가 있어요. 각 열에 대해 동일한 작업을 수행할 수도 있습니다.
fix_junk <- function(x){
#x <- as.character(x)
x[x == "B"] <- "b"
x
}
junk[] <- lapply(junk, fix_junk); junk # junk[] to get a data frame rather than a list
junk[1:3] <- lapply(junk[1:3], fix_junk); junk
stata.replace<-function(data,replacevar,replacevalue,ifs) {
ifs=parse(text=ifs)
yy=as.numeric(eval(ifs,data,parent.frame()))
x=sum(yy)
data=cbind(data,yy)
data[yy==1,replacevar]=replacevalue
message=noquote(paste0(x, " replacement are made"))
print(message)
return(data[,1:(ncol(data)-1)])
}
아래 줄을 사용하여 이 함수를 호출합니다.
d=stata.replace(d,"under20",1,"age<20")
언급URL : https://stackoverflow.com/questions/5824173/replace-a-value-in-a-data-frame-based-on-a-conditional-if-statement
'programing' 카테고리의 다른 글
cx_Oracle을 사용하여 사전 목록 만들기 (0) | 2023.07.19 |
---|---|
멀티프로세싱에서의 공유 메모리 객체 (0) | 2023.07.19 |
Python으로 Excel(xls) 파일 읽기/파싱 (0) | 2023.07.19 |
파이썬 다중 처리 풀 imap_unordered 호출의 진행 상황을 표시하시겠습니까? (0) | 2023.07.19 |
Windows 7 시스템의 MongoDB:연결할 수 없습니다. (0) | 2023.07.09 |