首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与前一列比较的数据帧列值的变化

与前一列比较的数据帧列值的变化
EN

Stack Overflow用户
提问于 2018-03-29 00:11:01
回答 3查看 67关注 0票数 2

我有一个很大的数据库,但是在这个练习中,让我们使用以下一个:

代码语言:javascript
复制
    c-1    c-2   c-3  c-4  c-5 c-6  
   1-14  14-29  NA    NA   NA  NA
   60-90  CF    CF    CF   CF  CF
    C     1-14  14-29 CF   NA  NA
   60-90  CF    CF    CF   NA  NA

我想要的是将前面列中有CF的所有列更改为HF,这样看起来如下所示:

代码语言:javascript
复制
   c-1    c-2   c-3  c-4  c-5 c-6  
   1-14  14-29  NA    NA   NA  NA
   60-90  CF    HF    HF   HF  HF
    C     1-14  14-29 CF   NA  NA
   60-90  CF    HF    HF   NA  NA

我试过用这样的申请表来做这件事,但它不能正常工作

代码语言:javascript
复制
function_a <- function (x) {ifelse(df[,i]=="CF" & df[,i-1]=="CF", "HF", df[,i])}    
new_df<- as.data.frame(lapply(length(df):1, function_a))

请记住,如果上一栏不是CF,我想保留原来的值,有什么简单的方法吗?在R基地?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-29 00:35:32

我喜欢这个问题,因为把它看作是一种滚动的应用程序是直接的,但在zoo::rollapply的意义上不是这样的(尽管在那里它也是可以管理的)。我说的是Reduce(..., accumulate=TRUE)的使用。

你的数据:

代码语言:javascript
复制
dat <- data.frame(
  c1 = c('1-14','60-90','C','60-90'),
  c2 = c('14-29','CF','1-14','CF'),
  c3 = c(NA,'CF','14-29','CF'),
  c4 = c(NA,'CF','CF','CF'),
  c5 = c(NA,'CF',NA,NA),
  c6 = c(NA,'CF',NA,NA),
  stringsAsFactors = FALSE
)

我在上一篇专栏中也添加了检查"HF"的逻辑,因为否则您将得到交替的"CF"/"HF"。我推断,无论上一篇专栏文章如何,NA始终应该是NA,因为这就是您的示例。(这一假设很容易被删除。)

代码语言:javascript
复制
func <- function(a, b) ifelse(! is.na(a) & ! is.na(b) & a %in% c("CF","HF"), "HF", b)

默认情况下,Reduce只返回最后一列的结果。使用accumulate=TRUE,它返回每个调用的结果(加上第一列),我们将使用该结果重新填充相同大小的帧。

代码语言:javascript
复制
df[] <- Reduce(func, df, right=FALSE, accumulate=TRUE)
df
#      c1    c2    c3   c4   c5   c6
# 1  1-14 14-29  <NA> <NA> <NA> <NA>
# 2 60-90    CF    HF   HF   HF   HF
# 3     C  1-14 14-29   CF <NA> <NA>
# 4 60-90    CF    HF   HF <NA> <NA>
票数 4
EN

Stack Overflow用户

发布于 2018-03-29 00:37:38

另一个建议的解决方案是转置矩阵,将矩阵滞后1行,然后检查滞后矩阵中的CF和转置矩阵中的CF,最后转回以获得所需的输出:

代码语言:javascript
复制
tdat <- t(dat)
lagged <- rbind(matrix(NA_character_, ncol=nrow(dat)), tdat[-nrow(tdat),])
tdat[lagged=="CF" & tdat=="CF"] <- "HF"
res <- t(tdat)
res

数据:

代码语言:javascript
复制
dat <- read.table(text="c-1    c-2   c-3  c-4  c-5 c-6  
1-14  14-29  NA    NA   NA  NA
60-90  CF    CF    CF   CF  CF
C     1-14  14-29 CF   NA  NA
60-90  CF    CF    CF   NA  NA", header=TRUE, check.names=FALSE)
票数 3
EN

Stack Overflow用户

发布于 2018-03-29 01:32:09

使用与原始数据大小相同的矩阵,查找第一次出现后在一行中出现的"CF"单元:

代码语言:javascript
复制
sel <- dat == "CF" & (!is.na(dat))
dat[col(dat) > max.col(sel, "first") & sel] <- "HF"
dat
#    c-1   c-2   c-3  c-4  c-5  c-6
#1  1-14 14-29  <NA> <NA> <NA> <NA>
#2 60-90    CF    HF   HF   HF   HF
#3     C  1-14 14-29   CF <NA> <NA>
#4 60-90    CF    HF   HF <NA> <NA>

使用@r2evans的dat对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49546093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档