2017-01-03 3 views
1

У меня есть кадр данных в R с четырьмя столбцами. То, что я хочу сделать, - это если условие удовлетворено строкой в ​​столбце AI, необходимо сопоставить значение этой строки в столбце C и найти последний экземпляр, значение которого появилось в столбце B, а затем добавить число в эту строку для столбца D. Вот пример того, что у меня есть, чего я хочу. Если DF $ а == 3, то соответствует значению этой строки в столбце C («Jim») до последнего времени оно появилось в столбце B, а затем добавить 3 к этой строке в столбце D.R найти последний экземпляр строки в одном столбце, который находится во втором столбце на основе условия

Have            Want 
a b c d         a b c d 
21 Jim - 0         21 Jim - 0 
2 Jim - 1         2 Jim - 4 
3 Stan Jim 2         3 Stan Jim 2 
2 Bill - 4         2 Bill - 4 

ответ

1
# a different sample with more variety was used 
#> df 
# a b c d 
#1: 21 Joel - 3 
#2: 2 Jim - 1 
#3: 2 Jim - 7 
#4: 3 Stan Jim 2 
#5: 2 Bill - 4 
#6: 3 Jim Joel 3 

# 1. determine the locations where a==3 
x = which(df$a == 3) 
# [1] 4 6 

# 2. determine the corresponding names from c 
y = df$c[which(df$a == 3)] 
# [1] "Jim" "Joel" 

# 3. determine the locations where to add +3 to d 
z = sapply(seq_along(y), function(i) max(grep(y[i], df$b[1:x[i]]))) 
# [1] 3 1 

# 4. add +3 to those 
df$d[z] = df$d[z] + 3 

# a b c d 
#1: 21 Joel - 6 
#2: 2 Jim - 1 
#3: 2 Jim - 10 
#4: 3 Stan Jim 2 
#5: 2 Bill - 4 
#6: 3 Jim Joel 3 

Примечание: выше случае предполагается, что значение, соответствующее y всегда можно найти в b. Но если возникает исключение: например, первая строка b имела jacky, тогда max() возвращает Inf. Поэтому предпочитают

df$d[z[!is.infinite(z)]] = df$d[z[!is.infinite(z)]] + 3 
+0

@ grig109 тоже отвечает на вопрос? ум, посещая здесь http://stackoverflow.com/help/someone-answers –

+1

Да, так оно и есть. Извините, что я только что начал тестировать свою проблему, и это сработало. Спасибо. – grig109

2

его немного grep тяжелый, но это работает:

df <- data.frame(a = c(21,2,3,2), 
       b = c("Jim", "Jim", "Stan", "Bill"), 
       c = c(NA, NA, "Jim", NA), 
       d = c(0,1,2,4)) 

target <- 3 

df$d[max(grep(df$c[grep(target, df$a)], df$b))] <- df$d[max(grep(df$c[grep(target, df$a)], df$b))] + target 
# or 
a_match_pos <- grep(target, df$a) 
last_c_match_pos <- max(grep(df$c[a_match_pos], df$b)) 
df$d[last_c_match_pos] <- df$d[last_c_match_pos] + target 

> df 
a b c d 
1 21 Jim <NA> 0 
2 2 Jim <NA> 4 
3 3 Stan Jim 2 
4 2 Bill <NA> 4