【问题标题】:Whats the R equivalent of the following Excel operation以下 Excel 操作的 R 等效项是什么
【发布时间】:2016-04-13 08:12:56
【问题描述】:

我有两列,col1 和 col2,我在 col3 下的 excel 中有以下公式

col1    col2    col3
0       0       0     
1       0       1
0       1       1
0       0       0
1       1       1
0       0       0

假设 col1 是单元格 A1

C2 formula: =A2
C3 formula: =IF(A3=1,1,IF(B2=1,0,C2))

我只能完成第一部分,

df$col3 <- ifelse(df$col1 == 1, 1, 0)

假设我的数据框名为“df”,我该如何在 R 中执行此操作

【问题讨论】:

  • 我不知道如何引用上一个单元格
  • @VincentGuillemot:我认为这里的问题是该函数是递归的,并且可能取决于以前的单元格值,因此很难进行矢量化,我会选择一个好的旧 for 循环...

标签: r excel


【解决方案1】:

我会使用一个简单的 for 循环:

df <- read.csv(text="col1,col2,expectedCol3
0,0,0     
1,0,1
0,1,1
0,0,0
1,1,1
0,0,0")

df$col3 <- NA # initialize column
for(i in 1:nrow(df)){
  if(i == 1){
    df$col3[i] <- df$col1[i]
  }else{
    df$col3[i] <- ifelse(df$col1[i] == 1, 1, ifelse(df$col2[i-1]==1,0,df$col3[i-1]))
  }
}

# are expected and calculated identical ?
identical(df$col3,df$expectedCol3)
# > TRUE

【讨论】:

  • 美丽而简单!!也喜欢使用相同的功能。非常感谢!
【解决方案2】:

使用dplyr::lag()函数:

df <- read.table(text = "col1    col2    col3
0       0       0     
1       0       1
0       1       1
0       0       0
1       1       1
0       0       0", header = TRUE)

library(dplyr)
result <- df %>%
  # C3 formula: =IF(A3=1,1,IF(B2=1,0,C2))
  mutate(res = ifelse(col1 == 1, 1, ifelse(lag(col2) == 1, 0, NA)),
         res = ifelse(is.na(res), lag(res), res))

# C2 formula: =A2
result$res[1] <- result$col1[1]

result
#   col1 col2 col3 res
# 1    0    0    0   0
# 2    1    0    1   1
# 3    0    1    1   1
# 4    0    0    0   0
# 5    1    1    1   1
# 6    0    0    0   0

【讨论】:

  • 不错!滞后功能对我来说是新事物
【解决方案3】:

您的 C3 公式是对 col1 和 col2 的或运算。如公式:

col3 = col1 OR col2

所以基本上做一个或操作:

在 R 中:

col1 <- c(0, 1, 0, 0, 1, 0)
col2 <- c(0, 0, 1, 0, 1, 0)
df <- data.frame(col1, col2)
df$col3 <- (df$col1 == 1 | df$col2 == 1) * 1
df

乘以 1 将逻辑值转换为数值。

在 Excel 中你也可以优化 col3:

C3 formula =N(OR(A2:B2))

再次重申:N() 公式将您的逻辑值转换为数字。

【讨论】:

  • 根据我给你的数据,你的答案是正确的,但它不符合公式中的逻辑,即col1=0和col2=1,col3=0的情况(给出前 col3 行不是 1)。感谢您的回答
  • 对,但是如果只有 0 和 1,并且您的结果不是矛盾的或基于更复杂的逻辑,您始终可以使用逻辑运算。 :-)
  • 不能反驳 :-)
【解决方案4】:
 df=data.frame(col1=c(0,1,0,0,1,0), col2=c(0,0,1,0,1,0))

 # shift B column to get "previous" value in every row.
 df$col2_prev=head(c(NA,df$col2),-1);

 df$col3 <- ifelse(is.na(df$col2_prev), 
                     df$col2,  
                     ifelse(df$col1 == 1, 1, 
                           ifelse(df$col2_prev == 1, 0, df$col2)
                           )
                  )

 df[c("col1","col2","col3")]

  col1 col2 col3
1    0    0    0
2    1    0    1
3    0    1    1
4    0    0    0
5    1    1    1
6    0    0    0

【讨论】:

    猜你喜欢
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多