R应用结果不一致

R应用结果不一致,r,R,我调用apply在数据帧的每一行上应用一个函数,但是我得到了一些奇怪的结果。当我第一次运行apply(运行#1)时,只有一部分行产生预期的结果。第二次运行apply后(运行#2),一些最初不正确的值是正确的。在运行#1之后,行不正确的情况下是一致的 assign_id()查找位于first中的id以及数据帧中的其他九列,返回与匹配列对应的整数 assign_id <- function(row) { if(is.na(row['first'])) { return(NULL)

我调用
apply
在数据帧的每一行上应用一个函数,但是我得到了一些奇怪的结果。当我第一次运行
apply
(运行#1)时,只有一部分行产生预期的结果。第二次运行
apply
后(运行#2),一些最初不正确的值是正确的。在运行#1之后,行不正确的情况下是一致的

assign_id()
查找位于
first
中的id以及数据帧中的其他九列,返回与匹配列对应的整数

assign_id <- function(row) {
  if(is.na(row['first'])) {
    return(NULL)
  }
  else if(row['first'] %in% c('none')) {
    return(0)
  }
  else if(row['first'] %in% as.character(row['one'])){
    return(1)
  }
  else if(row['first'] %in% as.character(row['two'])){
    return(2)
  }
  else if(row['first'] %in% as.character(row['three'])){
    return(3)
  }
  else if(row['first'] %in% as.character(row['four'])){
    return(4)
  }
  else if(row['first'] %in% as.character(row['five'])){
    return(5)
  }
  else if(row['first'] %in% as.character(row['six'])){
    return(6)
  }
  else if(row['first'] %in% as.character(row['seven'])){
    return(7)
  }
  else if(row['first'] %in% as.character(row['eight'])){
    return(8)
  }
  else if(row['first'] %in% as.character(row['nine'])){
    return(9)
  } else {
    return(11)
  }
}

df <- read.csv('df.csv')

# Run #1
df$id <- apply(df, 1, assign_id)
# All 'id' fields return 11
df[df$first %in% 55627, c('id', 'first', 'six')] 

> head(df[df$first %in% 55627, c('id', 'first', 'six')])
     id first    six
414  11 55627  55627
529  11 55627 118950
791  11 55627  55627
1570 11 55627 118950
1832 11 55627 118950
2116 11 55627 118950

# Run #2
df$id <- apply(df, 1, assign_id)
# All 'id' fields return the correct integer
df[df$first %in% 55627, c('id', 'first', 'six')] 

> head(df[df$first %in% 55627, c('id', 'first', 'six')])
     id first    six
414   6 55627  55627
529   5 55627 118950
791   6 55627  55627
1570  8 55627 118950
1832  5 55627 118950
2116  5 55627 118950
assign\u id在来自的一点帮助下,我想出了这个更简单的base-R解决方案:

df$id<-unlist(apply(df,1,function(x)
  ifelse(x["first"]=="none",0, which(as.integer(x["first"])==as.integer(x[2:10])))))

df$idI没有看到您在这个示例中的行为。旁注:您确定要从该函数返回空值吗?我想你可能是指安娜。空值通常意味着结果将保留为一个列表,而不是一个向量,如果取消列表,空值将被完全删除,从而缩短向量的长度。谢谢@joran,运行
apply()
一次后,您是否从Run#2获得结果?当我在第一个if条件中将
return(NULL)
更改为
return(NA)
时,运行#1和#2的结果相同,但都不正确。作为
apply
的替代方法,您可以在
时使用
dplyr::case\u,这也是矢量化的。谢谢,
dplyr::case\u-When()
mutate()的组合
似乎有效。我仍然对为什么原始函数不能工作感到困惑。或者
mapply(match,dd[[1]],split(dd[-1],1:nrow(dd))
?(我使用的是您链接的问答中的dd)是的,但我的速度要快得多:单位:秒expr min lq mean uq iod 4.141213 4.154136 4.154136 4.16706 frank 22.220058 22.220058 23.398411 23.398411 24.57676 max neval 4.16706 2 24.57676 2(我只运行了两次,因为对于您的解决方案,每轮超过20秒,运行默认的100次需要半个小时)很有趣。我想知道是不是
split
让它变慢了。另一个变体是
library(data.table);setDT(dd)[,first_match:=names(.SD)[mapply(match,first,transpose(.SD))],.SDcols=!“first”]
因此使用转置而不是拆分。在任何情况下,如果OP具有更好的结构化数据,我确信可以使用比您更快的方法。(
在数据帧上应用
的成本总是很高。)是的,好吧,data.table总是更快-我真的应该花时间去弄清楚它…数据结构也是如此,但我认为这是一个给定的条件。